ForgeTotal.js 5
nl

Total.js 5

Query Builder: DB() en NEWDB() met uw eigen database driver

Total.js 5 · total5@0.0.19 databasequerybuilder Uitgevoerd met Total.js 5

DB() bouwt een query zonder te weten welke database haar uitvoert, en NEWDB() registreert de driver die haar uitvoert. total5 zelf heeft geen SQL-driver: de query builder verzamelt wat je vraagt in een options-object en roept je driver ermee aan, en de driver (de jouwe, of een die in een module zit) vertaalt options naar SQL, een NoSQL-aanroep of iets anders.

  • NEWDB(driver) registreert de standaarddriver en NEWDB('name', driver) een benoemde. De driver is function(options, callback): antwoord met callback(error, response). Een tabel geschreven als name/table (DB().find('audit/log')) gebruikt de driver name en de tabel log; zonder voorvoegsel is de driver default.
  • De operaties beginnen met de vraag: find(table) (en in een afspraak) read(table) een object, of null Als er geen is, list(table) (een pagina van een array: response.page, limit en pages wordt toegevoegd aan wat de bestuurder terugkomt, dus de bestuurders moeten count) en insert(table, data)De bouwers hebben ook count, update, remove en queryHet werkt op dezelfde manier (de chauffeur options.exec met die naam).
  • Verwijder de vraag met: where(name, [comparer], value) (= Als er geen vergelijking is, fields('a,b'), sort(name, [true]) (true voor de afdaling, take(n) en page(page, limit)Andere wijzigingen bevatten id, in, skip, between en search.
  • Sluit af met .callback($): het resultaat gaat naar het antwoord van de actie $, of naar een functie (err, response) die je in plaats daarvan meegeeft.

Voor het volledige inheemse operationele catalogus, opschortend/fout gedrag en filters, zie Vraagde bouwcontractVoor SQL CRUD, commit en rollback, zie Query-builder-sqliteDe opties die de bestuurder ontvangt zijn duidelijke gegevens. het voorbeeld van de bestuurders slaat records in het geheugen en blootstelt het laatste ontvangen options object.

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);
}