ForgeTotal.js 5
fr

Total.js 5

Query Builder : DB() et NEWDB() avec votre propre pilote de données

Total.js 5 · total5@0.0.19 databasequerybuilder Exécutée avec Total.js 5

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 et NEWDB('name', driver) un pilote nommé. Le pilote est function(options, callback) : répondez avec callback(error, response). Une table écrite name/table (DB().find('audit/log')) utilise le pilote name et la table log ; sans préfixe, le pilote est default.
  • Les opérations commencent par la demande : find(table) (dans un arrondissement read(table) Un objet, ou null Lorsqu’il n’y a pas de list(table) (une page d’une série : response.page, limit et pages Il est ajouté à ce que le conducteur revient, de sorte que le chauffeur doit count) et insert(table, data)Le constructeur a aussi count, update, remove et queryIls travaillent de la même manière (le conducteur options.exec avec 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]) (true pour descendre, take(n) et page(page, limit)D’autres modifications incluent id, in, skip, between et search.
  • 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.

definitions/db.js
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' }]);
});
controllers/users.js
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);
}