This code provides a set of functions for interacting with a SQLite database containing movie information, including methods for searching by Levenshtein distance and retrieving actor and title data. The functions use a mix of synchronous and asynchronous programming, with prepared statements and promise chains to improve security, performance, and readability.
var importer = require('../Core');
var levSort = importer.import("sort by levenshtein distance");
var sqlite3 = require('better-sqlite3');
var movies = './movies.sqlite.db';
var db = new sqlite3(movies, {});
function getTitles(t) {
t = typeof t === 'string' ? [t] : t;
return db.prepare(`
SELECT *
FROM principals
WHERE tconst IN (${t.map(i => '?').join(',')})`).all(t);
}
function getTitlesByName(n) {
n = typeof n === 'string' ? [n] : n;
return db.prepare(`
SELECT *
FROM principals
WHERE nconst IN (${n.map(i => '?').join(',')})`).all(n);
}
function getActorsByTitles(t, n) {
t = typeof t === 'string' ? [t] : t;
n = typeof n === 'string' ? [n] : n;
return db.prepare(`
SELECT *
FROM principals
WHERE nconst IN (${n.map(i => '?').join(',')})
AND tconst IN (${t.map(i => '?').join(',')})`).all(n.concat(t));
}
var assignPromise = r => resolve => getExactName(r.nconst)
.then(result => Object.assign(r, result))
.then(resolve)
function getActorTitlesIntersection(n, t) {
var titles, actors;
return Promise.resolve()
.then(() => getTitlesByName(n))
.then(ts => titles = ts.map(t => t.tconst))
.then(() => getTitles(t))
.then(as => getActorsByTitles(titles, as.map(a => a.nconst)))
.then(r => importer.runAllPromises(r.map(r => assignPromise(r))))
}
function getTitleTitleIntersection(t) {
var titles = Array.from(arguments);
return Promise.resolve()
.then(() => getTitles(t))
.then(as => getActorsByTitles(titles.slice(1), as.map(a => a.nconst)))
.then(r => importer.runAllPromises(r.map(r => assignPromise(r))))
}
function getExactName(n) {
return Promise.resolve()
.then(() => db.prepare(`SELECT * FROM name WHERE nconst=?`).get(n))
}
function getExactTitle(t) {
return Promise.resolve()
.then(() => db.prepare(`SELECT * FROM titles WHERE tconst=?`).get(t))
}
function getTitle(t) {
var words = t.split(/\s+/ig);
return Promise.resolve()
.then(() => db.prepare(`
SELECT *
FROM titles
WHERE (${words.map(word => 'primaryTitle LIKE ?').join(' AND ')})
OR (${words.map(word => 'originalTitle LIKE ?').join(' AND ')})
`).all(words.map(w => `%${w}%`).concat(words.map(w => `%${w}%`))))
.then(results => levSort(results, t, r => r.primaryTitle)[0])
}
// https://v2.sg.media-imdb.com/suggests/w/werner%20herzog.json
$.async();
//getTitle('three colors: white')
getTitleTitleIntersection('tt0111507', 'tt0111495', 'tt0108394')
//getActorTitlesIntersection('nm0001348', 'tt0082694')
.then(r => $.sendResult(r))
.catch(e => $.sendError(e))
// close the database connection
.then(() => db.close())
```javascript
// Import required modules
const { import: levSort } = require('../Core');
const sqlite3 = require('better-sqlite3');
const dbPath = './movies.sqlite.db';
// Initialize the SQLite database
const db = new sqlite3(dbPath, {});
// Define utility functions
const getValues = (t) => t.map((item) => typeof item ==='string'? [item] : item);
// Function to get titles from the database
const getTitles = (t) => {
const query = `SELECT * FROM principals WHERE tconst IN (${getValues(t).map((i) => '?').join(',')})`;
return db.prepare(query).all(getValues(t));
};
// Function to get actors by title from the database
const getActorsByTitles = (t, n) => {
const query = `SELECT * FROM principals WHERE nconst IN (${getValues(n).map((i) => '?').join(',')}) AND tconst IN (${getValues(t).map((i) => '?').join(',')})`;
return db.prepare(query).all(getValues(n).concat(getValues(t)));
};
// Function to get a single actor's exact name from the database
const getExactName = (n) => {
const query = `SELECT * FROM name WHERE nconst=?`;
return db.prepare(query).get(n);
};
// Function to get a single title's exact details from the database
const getExactTitle = (t) => {
const query = `SELECT * FROM titles WHERE tconst=?`;
return db.prepare(query).get(t);
};
// Function to get a single title's details from the database using levenshtein distance
const getTitle = (t) => {
// Find words in the title
const words = t.split(/\s+/ig);
const query = `SELECT * FROM titles WHERE (${words.map((word) => 'primaryTitle LIKE?').join(' AND ')}) OR (${words.map((word) => 'originalTitle LIKE?').join(' AND ')})`;
return db.prepare(query).all(words.map((w) => `%${w}%`).concat(words.map((w) => `%${w}%`)));
};
// Function to get a title's intersection of titles from the database
const getTitleTitleIntersection = (t) => {
const titles = Array.from(arguments);
return Promise.resolve()
.then(() => getTitles(t))
.then((as) => getActorsByTitles(titles.slice(1), as.map((a) => a.nconst)))
.then((r) => levSort(r.map((r) => r), t, (r) => r.primaryTitle)[0]);
};
// Function to get an actor's intersection of titles from the database
const getActorTitlesIntersection = (n, t) => {
const titles = getTitles(n);
const actors = getTitles(t);
return Promise.all([titles, actors]).then((results) => {
const titlesArray = results[0].map((t) => t.tconst);
const actorsArray = results[1].map((a) => a.nconst);
return levSort(getActorsByTitles(titlesArray, actorsArray), t, (r) => r.primaryTitle)[0];
});
};
// Function to assign exact name to an actor
const assignPromise = (r) => {
return getExactName(r.nconst).then((result) => Object.assign(r, result));
};
// Initialize the database connection
db.close();
// Usage
getTitle('three colors: white')
.then((result) => console.log(result))
.catch((error) => console.error(error));
getTitleTitleIntersection('tt0111507', 'tt0111495', 'tt0108394')
.then((result) => console.log(result))
.catch((error) => console.error(error));
getActorTitlesIntersection('nm0001348', 'tt0082694')
.then((result) => console.log(result))
.catch((error) => console.error(error));
```
This code is a set of functions for interacting with a SQLite database containing movie information. It provides methods for retrieving actor and title data, including functionality for searching by Levenshtein distance.
The code requires two external modules:
better-sqlite3
for interacting with the SQLite database.../Core
containing a function import
for importing modules and runAllPromises
for running multiple promises concurrently.getTitles(t)
:
principals
table where the tconst
column matches any of the provided values.getTitlesByName(n)
:
principals
table where the nconst
column matches any of the provided values.getActorsByTitles(t, n)
:
principals
table where the tconst
column matches any of the provided titles and the nconst
column matches any of the provided names.getActorTitlesIntersection(n, t)
:
getTitleTitleIntersection(t)
:
getExactName(n)
:
name
table where the nconst
column matches the provided value.getExactTitle(t)
:
titles
table where the tconst
column matches the provided value.assignPromise(r)
:
better-sqlite3
module is used for interacting with the SQLite database.../Core
module contains functions for importing modules and running multiple promises concurrently.assignPromise
demonstrates how to modify an object in a promise chain.