Query Builder : DB() et NEWDB() avec votre propre pilote de données
DB() construit une requête sans savoir quelle base de données l'exécutera, et NEWDB() enregistre le pilote qui l'exécute. total5 n'a lui-même aucun pilote SQL : le query builder rassemble ce que vous demandez dans un objet options et appelle votre pilote avec lui, et le pilote (le vôtre, ou un fourni par un module) traduit options en SQL, en appel NoSQL ou en autre chose.
NEWDB(driver)enregistre le pilote par défaut etNEWDB('name', driver)un pilote nommé. Le pilote estfunction(options, callback): répondez aveccallback(error, response). Une table écritename/table(DB().find('audit/log')) utilise le pilotenameet la tablelog; sans préfixe, le pilote estdefault.- Les opérations commencent par la demande :
find(table)(dans un arrondissementread(table)Un objet, ounullLorsqu’il n’y a pas delist(table)(une page d’une série :response.page,limitetpagesIl est ajouté à ce que le conducteur revient, de sorte que le chauffeur doitcount) etinsert(table, data)Le constructeur a aussicount,update,removeetqueryIls travaillent de la même manière (le conducteuroptions.execavec ce nom). - Réparer la question avec :
where(name, [comparer], value)(=Lorsqu’il n’y a pas de comparateur,fields('a,b'),sort(name, [true])(truepour descendre,take(n)etpage(page, limit)D’autres modifications incluentid,in,skip,betweenetsearch. - Terminez avec
.callback($): le résultat va à la réponse de l'action$, ou à une fonction(err, response)que vous passez à la place.
Pour le catalogue d'opérations native complet, le comportement d'erreur et les formes de filtre, voir Contrat de constructeurPour SQL CRUD, Command et Rollback, voir Question-constructeur SqliteLes options que le conducteur reçoit sont des données claires.L'exemple du conducteur stocke les enregistrements dans la mémoire et expose l'objet dernier options reçu.
const users = [
{ id: 1, name: 'Ann', age: 31 },
{ id: 2, name: 'Bob', age: 17 },
{ id: 3, name: 'Cy', age: 45 }
];
F.seen = [];
// The default driver: it understands only "age >= value" and "id = value", which is all this example asks
NEWDB(function(options, callback) {
F.seen.push(JSON.parse(JSON.stringify(options)));
let rows = users.slice();
for (let f of options.filter) {
if (f.type === 'where' && f.name === 'age' && f.comparer === '>=')
rows = rows.filter(n => n.age >= f.value);
else if (f.type === 'where' && f.name === 'id')
rows = rows.filter(n => n.id === f.value);
}
switch (options.exec) {
case 'find':
case 'read':
if (options.sort && options.sort[0] === 'name_desc')
rows.sort((a, b) => a.name < b.name ? 1 : -1);
if (options.take)
rows = rows.slice(0, options.take);
return callback(null, rows);
case 'list':
rows.count = rows.length;
return callback(null, rows);
case 'insert':
users.push(Object.assign({ id: users.length + 1 }, options.payload));
return callback(null, users[users.length - 1]);
default:
return callback('The driver does not know ' + options.exec);
}
});
// A second driver, used by the tables that start with "audit/"
NEWDB('audit', function(options, callback) {
F.seen.push({ driver: 'audit', table: options.table });
callback(null, [{ event: 'login' }]);
});exports.install = function() {
ROUTE('GET /adults/', adults);
ROUTE('GET /user/{id}/', user);
ROUTE('POST /users/', create);
ROUTE('GET /page/', page);
ROUTE('GET /audit/', audit);
ROUTE('GET /seen/', seen);
};
function adults($) {
DB().find('users').where('age', '>=', 18).fields('id,name').sort('name', true).take(5).callback($);
}
function user($) {
DB().read('users').where('id', +$.params.id).callback($);
}
function create($) {
DB().insert('users', { name: $.body.name, age: $.body.age }).callback($);
}
function page($) {
DB().list('users').page(1, 2).callback(function(err, response) {
$.json({ err: err, count: response.count, page: response.page, limit: response.limit, pages: response.pages });
});
}
function audit($) {
DB().find('audit/log').callback($);
}
function seen($) {
$.json(F.seen);
}