ForgeTotal.js 5
it

Total.js 5

Operazioni di QueryBuilder, filtri e contratti di driver

Total.js 5 · total5@0.0.19 total5reference Eseguita con Total.js 5

Questa pagina copre il QueryBuilder nativo di total5@0.0.19 (querybuilder.js). DB() restituisce un controller di coda. Ogni operazione pianifica una chiamata al driver; aggiungi filtri e callback in modo sincrono prima che venga eseguita. NEWDB(name, driver) registra una connessione. NEWDB(name) la deregistra. In questa coda non ci sono motore di database né transazione impliciti.

L'esempio del driver restituisce le opzioni ricevute.Per eseguire un'operazione di database, implementare quella operazione nel driver. Query-costruttore-sqlite.

OperazioniIl driver riceve
find/all(table), read/one(table), list(table)exec, table; read imposta first:true, take:1; list per default usa take:100, skip:0
check(table), count(table)check imposta first:1, take:1; il driver definisce il valore del risultato
insert/ins(table, data)payload
update/modify/mod/upd(table, data, upsert)payload, upsert; un risultato zero attiva un secondo insert quando l'upsert è abilitato
remove/rem(table), truncate/clear(table), drop(table)Il exec corrispondente; le operazioni distruttive richiedono il supporto del driver
scalar(table, type, key, key2)scalar:{type,key,key2}; un key omesso diventa *
command(table, name)command:name
query(sql, params) oppure query(connection, sql, params)Testo grezzo in query, valori in params, la tabella è vuota; l'associazione dei parametri SQL è responsabilità del driver
Metodi di queryOpzioni / comportamento
where(name, [comparer], value), equal(object), id(value), userid(value)Scorciatoia di uguaglianza; == diventa =, != diventa ; gli ID in array usano in
in/notin(name, values, [idField]), between(name,a,b), or(fn)Filtrano i record; or raggruppa i record aggiunti dentro fn(builder)
array(name,[comparer],value)Comparatore predefinito &&; l'interpretazione spetta al driver
month/day/year/hour/minute(name,[comparer],value)Filtri per parte di data; comparatore predefinito =
search(name,value,[where]), contains(name), empty(name)Filtrano i record; la semantica di corrispondenza spetta al driver
query(fragment), join(name,table,type,a,b), permit(name,type,values,userid,required)Filtri specifici del driver; i frammenti grezzi devono provenire da codice applicativo fidato
fields(csv), returning(csv)Array di nomi di campo ripuliti, non escaping SQL né autorizzazione
sort(name, descending), gridsort(csv,[localized])Stringhe di ordinamento; true o desc selezionano il decrescente
take/limit(n), skip(n), page(page,limit), paginate(page,limit,max)Offset/limiti; paginate limita il tetto, page no
first(), primarykey(name), schema(name), language(value,prefix,skip), debug()Metadati per il driver; first scarta anche l'array di un risultato
gridfilter(name,query,type,[key]), autoquery(query,schema,sort,max)Convertono i parametri di query della griglia in opzioni. autoquery limita i campi richiesti e le chiavi di ordinamento al suo schema dichiarato
gridfields(fields,allowed)Utilizzare fields() con la propria lista di permissioni: è il modo testato per scegliere le colonne
callback/pipe(fn), promise(), done($,fn,param)Completamento; le promise vengono rifiutate in caso di errore del driver
data(fn), fail(fn), error/err(message,reverse)Hook di successo/fallimento; error() rifiuta i risultati vuoti, reverse:true rifiuta i risultati truthy (incluso un array vuoto)
set(name), nobind()Danno un nome al risultato in coda, oppure non sostituiscono l'output della coda
insert(fn,param) su un builder di updateModifica il payload prima dell'insert di ripiego di un upsert
audit($,message,type)Chiama variables() e audit() del contesto fornito dopo una risposta riuscita del driver

Metodi del controller: callback/pipe, promise, done, debug, language, load(connection, options) e exec(options, callback). load copia un sottoinsieme definito di opzioni serializzate; exec smista i nomi di operazione supportati. next/free sono interni del ciclo di vita. Una coda si ferma dopo un errore del driver; non annulla le scritture precedenti.

definitions/contract.js
NEWDB('contract', function(options, callback) {
	if (options.table === 'failure')
		return callback(new Error('driver failed'));
	if (options.table === 'empty')
		return callback(null, []);
	if (options.table === 'upsert') {
		MAIN.upsert.push(JSON.parse(JSON.stringify(options)));
		return callback(null, options.exec === 'update' ? 0 : options.payload);
	}
	if (options.exec === 'list')
		return callback(null, { items: [], count: 12 });
	callback(null, options.first ? [options] : options);
});
MAIN.upsert = [];
controllers/contract.js
exports.install = function() {
	ROUTE('GET /contract/', contract);
};

async function contract($) {
	try {
		var out = {};
		var methods = ['find', 'all', 'read', 'one', 'list', 'check', 'count', 'insert', 'ins', 'update', 'modify', 'mod', 'upd', 'remove', 'rem', 'truncate', 'clear', 'drop'];
		out.operations = {};
		for (var method of methods)
			out.operations[method] = await DB()[method]('contract/items', { name: 'Ann' }).promise();
		out.scalar = await DB().scalar('contract/items', 'sum', 'amount', 'group').promise();
		out.command = await DB().command('contract/items', 'vacuum').promise();
		out.raw = await DB().query('contract', 'SELECT ?', [7]).promise();
		out.filters = await DB().find('contract/items').id([1, 2]).userid({ id: 'u1' }).equal({ active: true }).where('age', '!=', 0).in('team', [{ id: 'a' }], 'id').notin('team', 'b').between('age', 18, 65).or(function(q) { q.where('role', 'a').where('role', 'b'); }).array('tags', ['x']).month('created', 1).day('created', 2).year('created', '>=', 2020).hour('created', 3).minute('created', 4).search('name', 'ann', 'beg').contains('email').empty('deleted').query('trusted_fragment').join('team', 'teams', 'left', 'a.id', 'b.id').permit('permissions', 'RW', ['team'], 'u1', false).promise();
		out.options = await DB().find('contract/items').fields('id, name').returning('id, name').sort('name', true).gridsort('id_asc').limit(5).skip(2).primarykey('uid').schema('public').language({ language: 'es' }, '_').debug().promise();
		out.page = await DB().list('contract/items').paginate('2', '500', 10).promise();
		out.grid = await DB().find('contract/items').autoquery({ fields: 'id,password', sort: 'password_desc,name_desc', page: '2', limit: '500', age: '>18' }, 'id:String,name:String,age:Number', 'id_asc', 10).promise();
		out.gridfields = await DB().find('contract/items').gridfields('id', 'id,name').promise();
		var queue = DB();
		queue.read('contract/items').set('one');
		queue.count('contract/items').set('count');
		queue.find('contract/items').nobind();
		out.queue = await queue.promise();
		var hooks = [];
		await DB().read('contract/empty').data(function(v) { hooks.push(v === null ? 'null' : 'value'); }).promise();
		try { await DB().read('contract/empty').error('missing').fail(function() { hooks.push('fail'); }).promise(); } catch (e) { out.missing = String(e); }
		try { await DB().find('contract/failure').promise(); } catch (e) { out.failure = String(e); }
		out.hooks = hooks;
		out.upsert = await DB().update('contract/upsert', { name: 'new' }, true).where('id', 7).insert(function(payload, role) { payload.role = role; }, 'member').promise();
		out.upsertCalls = MAIN.upsert;
		out.load = await DB().load('contract', { table: 'items', exec: 'find', take: 2, filter: [] }).promise();
		$.json(out);
	} catch (e) { $.invalid(e); }
}