1 /**
    2  * WARNING: automatically generated by ort 0.12.7.
    3  * DO NOT EDIT!
    4  * @packageDocumentation
    5  */
    6 
    7 import bcrypt from 'bcrypt';
    8 import Database from 'better-sqlite3';
    9 
   10 /**
   11  * Namespace for data interfaces and representative classes.  The 
   12  * interfaces are for the data itself, while the classes manage roles and 
   13  * metadata.
   14  */
   15 export namespace ortns {
   16 	/**
   17 	 * Birthsex of individual
   18 	 */
   19 	export enum sex {
   20 		/**
   21 		 * Male
   22 		 */
   23 		male = '0',
   24 		/**
   25 		 * Female
   26 		 */
   27 		female = '1',
   28 		/**
   29 		 * Other
   30 		 */
   31 		other = '2'
   32 	}
   33 
   34 	/**
   35 	 * Controlling organisation.
   36 	 */
   37 	export interface companyData {
   38 		/**
   39 		 * Name of the organisation.
   40 		 */
   41 		name: string;
   42 		id: BigInt;
   43 		/**
   44 		 * Simply a check for null values.
   45 		 */
   46 		somenum: BigInt|null;
   47 	}
   48 
   49 	function db_export_company(role: string, obj: companyData): any
   50 	{
   51 		const res: any = {}
   52 
   53 		res['name'] = obj['name'];
   54 		res['id'] = obj['id'].toString();
   55 		res['somenum'] = (obj['somenum'] === null) ?
   56 			null : obj['somenum'].toString();
   57 
   58 		return res;
   59 	}
   60 
   61 	/**
   62 	 * Class instance of {@link ortns.companyData}.
   63 	 */
   64 	export class company {
   65 		readonly #role: string;
   66 		readonly obj: ortns.companyData;
   67 
   68 		/**
   69 		 * A {@link ortns.companyData} as extracted from the database in 
   70 		 * a particular role.
   71 		 * @param role The role in which this was extracted from the 
   72 		 * database. When exported, this role will be checked for 
   73 		 * permission to export.
   74 		 * @param obj The raw data.
   75 		 */
   76 		constructor(role: string, obj: ortns.companyData)
   77 		{
   78 			this.#role = role;
   79 			this.obj = obj;
   80 		}
   81 
   82 		/**
   83 		 * Export the contained {@link ortns.companyData} respecting 
   84 		 * fields not exported, roles, etc.  It's safe to call 
   85 		 * `JSON.stringify()` on the returned object to write responses.
   86 		 */
   87 		export(): any
   88 		{
   89 			return db_export_company(this.#role, this.obj);
   90 		}
   91 	}
   92 
   93 	/**
   94 	 * A regular user.
   95 	 */
   96 	export interface userData {
   97 		/**
   98 		 * This struct will be filled in from an inner join
   99 		 *     on the "cid" variable.
  100 		 */
  101 		company: ortns.companyData;
  102 		/**
  103 		 * A foreign key reference.
  104 		 */
  105 		cid: BigInt;
  106 		/**
  107 		 * User's birth sex.
  108 		 */
  109 		sex: ortns.sex;
  110 		/**
  111 		 * Password hash.
  112 		 *     This is passed to inserts and updates as a password,
  113 		 *     then hashed within the implementation and extracted
  114 		 *     (in listings and searches) as the hash value.
  115 		 */
  116 		hash: string;
  117 		/**
  118 		 * Unique e-mail address.
  119 		 */
  120 		email: string;
  121 		/**
  122 		 * A PNG image or something.
  123 		 */
  124 		image: Buffer|null;
  125 		/**
  126 		 * User's full name.
  127 		 */
  128 		name: string;
  129 		uid: BigInt;
  130 	}
  131 
  132 	function db_export_user(role: string, obj: userData): any
  133 	{
  134 		const res: any = {}
  135 
  136 		res['company'] = db_export_company(role, obj['company'])
  137 		res['cid'] = obj['cid'].toString();
  138 		res['sex'] = obj['sex'];
  139 		/**
  140 		 * Don't output hash: password.
  141 		 */
  142 		res['email'] = obj['email'];
  143 		res['image'] = (obj['image'] === null) ?
  144 			null : obj['image'].toString('base64');
  145 		res['name'] = obj['name'];
  146 		res['uid'] = obj['uid'].toString();
  147 
  148 		return res;
  149 	}
  150 
  151 	/**
  152 	 * Class instance of {@link ortns.userData}.
  153 	 */
  154 	export class user {
  155 		readonly #role: string;
  156 		readonly obj: ortns.userData;
  157 
  158 		/**
  159 		 * A {@link ortns.userData} as extracted from the database in a 
  160 		 * particular role.
  161 		 * @param role The role in which this was extracted from the 
  162 		 * database. When exported, this role will be checked for 
  163 		 * permission to export.
  164 		 * @param obj The raw data.
  165 		 */
  166 		constructor(role: string, obj: ortns.userData)
  167 		{
  168 			this.#role = role;
  169 			this.obj = obj;
  170 		}
  171 
  172 		/**
  173 		 * Export the contained {@link ortns.userData} respecting fields 
  174 		 * not exported, roles, etc.  It's safe to call 
  175 		 * `JSON.stringify()` on the returned object to write responses.
  176 		 */
  177 		export(): any
  178 		{
  179 			return db_export_user(this.#role, this.obj);
  180 		}
  181 	}
  182 
  183 	/**
  184 	 * Authenticated session.
  185 	 */
  186 	export interface sessionData {
  187 		user: ortns.userData;
  188 		/**
  189 		 * Associated user.
  190 		 */
  191 		userid: BigInt;
  192 		/**
  193 		 * Random cookie.
  194 		 */
  195 		token: BigInt;
  196 		mtime: BigInt;
  197 		id: BigInt;
  198 	}
  199 
  200 	function db_export_session(role: string, obj: sessionData): any
  201 	{
  202 		const res: any = {}
  203 
  204 		res['user'] = db_export_user(role, obj['user'])
  205 		res['userid'] = obj['userid'].toString();
  206 		res['token'] = obj['token'].toString();
  207 		res['mtime'] = obj['mtime'].toString();
  208 		res['id'] = obj['id'].toString();
  209 
  210 		return res;
  211 	}
  212 
  213 	/**
  214 	 * Class instance of {@link ortns.sessionData}.
  215 	 */
  216 	export class session {
  217 		readonly #role: string;
  218 		readonly obj: ortns.sessionData;
  219 
  220 		/**
  221 		 * A {@link ortns.sessionData} as extracted from the database in 
  222 		 * a particular role.
  223 		 * @param role The role in which this was extracted from the 
  224 		 * database. When exported, this role will be checked for 
  225 		 * permission to export.
  226 		 * @param obj The raw data.
  227 		 */
  228 		constructor(role: string, obj: ortns.sessionData)
  229 		{
  230 			this.#role = role;
  231 			this.obj = obj;
  232 		}
  233 
  234 		/**
  235 		 * Export the contained {@link ortns.sessionData} respecting 
  236 		 * fields not exported, roles, etc.  It's safe to call 
  237 		 * `JSON.stringify()` on the returned object to write responses.
  238 		 */
  239 		export(): any
  240 		{
  241 			return db_export_session(this.#role, this.obj);
  242 		}
  243 	}
  244 }
  245 
  246 /**
  247  * Primary database object. Only one of these should exist per running 
  248  * node.js server.
  249  */
  250 export class ortdb {
  251 	db: Database.Database;
  252 	/**
  253 	 * The ort-nodejs version used to produce this file.
  254 	 */
  255 	readonly version: string = '0.12.7';
  256 	/**
  257 	 * The numeric (monotonically increasing) ort-nodejs version used to 
  258 	 * produce this file.
  259 	 */
  260 	readonly vstamp: number = 11308;
  261 
  262 	/**
  263 	 * @param dbname The file-name of the database relative to the 
  264 	 * running application.
  265 	 */
  266 	constructor(dbname: string) {
  267 		this.db = new Database(dbname);
  268 		this.db.defaultSafeIntegers(true);
  269 	}
  270 
  271 	/**
  272 	 * Create a connection to the database. This should be called for 
  273 	 * each sequence representing a single operator. In web applications, 
  274 	 * for example, this should be called for each request.
  275 	 */
  276 	connect(): ortctx
  277 	{
  278 		return new ortctx(this);
  279 	}
  280 }
  281 
  282 namespace ortstmt {
  283 	export enum ortstmt {
  284 		STMT_company_BY_UNIQUE_id,
  285 		STMT_company_BY_SEARCH_0,
  286 		STMT_company_INSERT,
  287 		STMT_company_DELETE_0,
  288 		STMT_user_BY_UNIQUE_email,
  289 		STMT_user_BY_UNIQUE_uid,
  290 		STMT_user_BY_SEARCH_0,
  291 		STMT_user_BY_SEARCH_1,
  292 		STMT_user_BY_SEARCH_2,
  293 		STMT_user_INSERT,
  294 		STMT_user_UPDATE_0,
  295 		STMT_user_UPDATE_1,
  296 		STMT_user_DELETE_0,
  297 		STMT_session_BY_UNIQUE_id,
  298 		STMT_session_BY_SEARCH_0,
  299 		STMT_session_INSERT,
  300 		STMT_session_DELETE_0,
  301 	}
  302 
  303 	export function stmtBuilder(idx: ortstmt): string
  304 	{
  305 		return ortstmts[idx];
  306 	}
  307 
  308 	const ortstmts: readonly string[] = [
  309 		/* STMT_company_BY_UNIQUE_id */
  310 		'SELECT ' + ort_schema_company('company') + ' FROM company WHERE company.id = ?',
  311 		/* STMT_company_BY_SEARCH_0 */
  312 		'SELECT ' + ort_schema_company('company') + ' FROM company '
  313 			+ 'WHERE company.somenum ISNULL',
  314 		/* STMT_company_INSERT */
  315 		'INSERT INTO company (name,somenum) VALUES (?,?)',
  316 		/* STMT_company_DELETE_0 */
  317 		'DELETE FROM company',
  318 		/* STMT_user_BY_UNIQUE_email */
  319 		'SELECT ' + ort_schema_user('user') + ',' + ort_schema_company('_a') + ' FROM user '
  320 			+ 'INNER JOIN company AS _a ON _a.id=user.cid '
  321 			+ 'WHERE user.email = ?',
  322 		/* STMT_user_BY_UNIQUE_uid */
  323 		'SELECT ' + ort_schema_user('user') + ',' + ort_schema_company('_a') + ' FROM user '
  324 			+ 'INNER JOIN company AS _a ON _a.id=user.cid '
  325 			+ 'WHERE user.uid = ?',
  326 		/* STMT_user_BY_SEARCH_0 */
  327 		'SELECT ' + ort_schema_user('user') + ',' + ort_schema_company('_a') + ' FROM user '
  328 			+ 'INNER JOIN company AS _a ON _a.id=user.cid '
  329 			+ 'WHERE user.name = ? LIMIT 5',
  330 		/* STMT_user_BY_SEARCH_1 */
  331 		'SELECT ' + ort_schema_user('user') + ',' + ort_schema_company('_a') + ' FROM user '
  332 			+ 'INNER JOIN company AS _a ON _a.id=user.cid '
  333 			+ 'WHERE user.email = ?',
  334 		/* STMT_user_BY_SEARCH_2 */
  335 		'SELECT ' + ort_schema_user('user') + ',' + ort_schema_company('_a') + ' FROM user '
  336 			+ 'INNER JOIN company AS _a ON _a.id=user.cid '
  337 			+ 'WHERE user.uid = ? ORDER BY _a.name ASC',
  338 		/* STMT_user_INSERT */
  339 		'INSERT INTO user (cid,sex,hash,email,image,name) VALUES '
  340 			+ '(?,?,?,?,?,?)',
  341 		/* STMT_user_UPDATE_0 */
  342 		'UPDATE user SET hash = ? WHERE uid = ?',
  343 		/* STMT_user_UPDATE_1 */
  344 		'UPDATE user SET email = ? WHERE uid = ?',
  345 		/* STMT_user_DELETE_0 */
  346 		'DELETE FROM user',
  347 		/* STMT_session_BY_UNIQUE_id */
  348 		'SELECT ' + ort_schema_session('session') + ',' + ort_schema_user('_b') + ',' 
  349 			+ ort_schema_company('_c') + ' FROM session '
  350 			+ 'INNER JOIN user AS _b ON _b.uid=session.userid '
  351 			+ 'INNER JOIN company AS _c ON _c.id=_b.cid '
  352 			+ 'WHERE session.id = ?',
  353 		/* STMT_session_BY_SEARCH_0 */
  354 		'SELECT ' + ort_schema_session('session') + ',' + ort_schema_user('_b') + ',' 
  355 			+ ort_schema_company('_c') + ' FROM session '
  356 			+ 'INNER JOIN user AS _b ON _b.uid=session.userid '
  357 			+ 'INNER JOIN company AS _c ON _c.id=_b.cid '
  358 			+ 'WHERE _c.name = ? AND session.mtime = ?',
  359 		/* STMT_session_INSERT */
  360 		'INSERT INTO session (userid,token,mtime) VALUES (?,?,?)',
  361 		/* STMT_session_DELETE_0 */
  362 		'DELETE FROM session WHERE id = ?',
  363 	];
  364 
  365 	function ort_schema_company(v: string): string
  366 	{
  367 		return v + '.name' + ',' +
  368 		       v + '.id' + ',' +
  369 		       v + '.somenum';
  370 	}
  371 
  372 	function ort_schema_user(v: string): string
  373 	{
  374 		return v + '.cid' + ',' +
  375 		       v + '.sex' + ',' +
  376 		       v + '.hash' + ',' +
  377 		       v + '.email' + ',' +
  378 		       v + '.image' + ',' +
  379 		       v + '.name' + ',' +
  380 		       v + '.uid';
  381 	}
  382 
  383 	function ort_schema_session(v: string): string
  384 	{
  385 		return v + '.userid' + ',' +
  386 		       v + '.token' + ',' +
  387 		       v + '.mtime' + ',' +
  388 		       v + '.id';
  389 	}
  390 }
  391 
  392 /**
  393  * Manages all access to the database. This object should be used for the 
  394  * lifetime of a single 'request', such as a request for a web 
  395  * application.
  396  */
  397 export class ortctx {
  398 	#role: string = 'default';
  399 	readonly #o: ortdb;
  400 
  401 	constructor(o: ortdb) {
  402 		this.#o = o;
  403 	}
  404 
  405 	db_trans_open_immediate(id: number): void
  406 	{
  407 		this.#o.db.exec('BEGIN TRANSACTION IMMEDIATE');
  408 	}
  409 
  410 	db_trans_open_deferred(id: number): void
  411 	{
  412 		this.#o.db.exec('BEGIN TRANSACTION DEFERRED');
  413 	}
  414 
  415 	db_trans_open_exclusive(id: number): void
  416 	{
  417 		this.#o.db.exec('BEGIN TRANSACTION EXCLUSIVE');
  418 	}
  419 
  420 	db_trans_rollback(id: number): void
  421 	{
  422 		this.#o.db.exec('ROLLBACK TRANSACTION');
  423 	}
  424 
  425 	db_trans_commit(id: number): void
  426 	{
  427 		this.#o.db.exec('COMMIT TRANSACTION');
  428 	}
  429 
  430 	private db_company_fill(data: {row: any[], pos: number}):
  431 		ortns.companyData
  432 	{
  433 		const obj: ortns.companyData = {
  434 			'name': <string>data.row[data.pos + 0],
  435 			'id': <BigInt>data.row[data.pos + 1],
  436 			'somenum': <BigInt|null>data.row[data.pos + 2],
  437 		};
  438 		data.pos += 3;
  439 		return obj;
  440 	}
  441 
  442 	/**
  443 	 * Insert a new row into the database. Only native (and non-rowid) 
  444 	 * fields may be set.
  445 	 * @param v1 name
  446 	 * @param v2 somenum
  447 	 * @return New row's identifier on success or <0 otherwise.
  448 	 */
  449 	db_company_insert(v1: string, v2: BigInt|null): BigInt
  450 	{
  451 		const parms: any[] = [];
  452 		let info: Database.RunResult;
  453 		const stmt: Database.Statement =
  454 			this.#o.db.prepare(ortstmt.stmtBuilder
  455 			(ortstmt.ortstmt.STMT_company_INSERT));
  456 
  457 		parms.push(v1);
  458 		parms.push(v2);
  459 
  460 		try {
  461 			info = stmt.run(parms);
  462 		} catch (er) {
  463 			return BigInt(-1);
  464 		}
  465 
  466 		return BigInt(info.lastInsertRowid);
  467 	}
  468 
  469 	/**
  470 	 * Search for a set of {@link ortns.company}.
  471 	 * The following fields are constrained by unary operations: 
  472 	 * somenum (checked is null)
  473 	 * @return Result of null if no results found.
  474 	 */
  475 	db_company_list_by_somenum_isnull(): ortns.company[]
  476 	{
  477 		const parms: any[] = [];
  478 		const stmt: Database.Statement =
  479 			this.#o.db.prepare(ortstmt.stmtBuilder
  480 			(ortstmt.ortstmt.STMT_company_BY_SEARCH_0));
  481 		stmt.raw(true);
  482 
  483 		const rows: any[] = stmt.all(parms);
  484 		const objs: ortns.company[] = [];
  485 		let i: number;
  486 
  487 		for (i = 0; i < rows.length; i++) {
  488 			const obj: ortns.companyData =
  489 				this.db_company_fill({row: <any[]>rows[i], pos: 0});
  490 			objs.push(new ortns.company(this.#role, obj));
  491 		}
  492 		return objs;
  493 	}
  494 
  495 	/**
  496 	 * 
  497 	 */
  498 	db_company_delete(): void
  499 	{
  500 		const parms: any[] = [];
  501 		let info: Database.RunResult;
  502 		const stmt: Database.Statement =
  503 			this.#o.db.prepare(ortstmt.stmtBuilder
  504 			(ortstmt.ortstmt.STMT_company_DELETE_0));
  505 
  506 
  507 		stmt.run(parms);
  508 	}
  509 
  510 	private db_user_fill(data: {row: any[], pos: number}):
  511 		ortns.userData
  512 	{
  513 		const obj: ortns.userData = {
  514 			/* A dummy value for now. */
  515 			'company': <ortns.companyData>{},
  516 			'cid': <BigInt>data.row[data.pos + 0],
  517 			'sex': <ortns.sex>data.row[data.pos + 1].toString(),
  518 			'hash': <string>data.row[data.pos + 2],
  519 			'email': <string>data.row[data.pos + 3],
  520 			'image': <Buffer|null>data.row[data.pos + 4],
  521 			'name': <string>data.row[data.pos + 5],
  522 			'uid': <BigInt>data.row[data.pos + 6],
  523 		};
  524 		data.pos += 7;
  525 		obj.company = this.db_company_fill(data);
  526 		return obj;
  527 	}
  528 
  529 	/**
  530 	 * Insert a new row into the database. Only native (and non-rowid) 
  531 	 * fields may be set.
  532 	 * @param v1 cid
  533 	 * @param v2 sex
  534 	 * @param v3 hash
  535 	 * @param v4 email
  536 	 * @param v5 image
  537 	 * @param v6 name
  538 	 * @return New row's identifier on success or <0 otherwise.
  539 	 */
  540 	db_user_insert(v1: BigInt, v2: ortns.sex, v3: string, v4: string,
  541 		v5: Buffer|null, v6: string): BigInt
  542 	{
  543 		const parms: any[] = [];
  544 		let info: Database.RunResult;
  545 		const stmt: Database.Statement =
  546 			this.#o.db.prepare(ortstmt.stmtBuilder
  547 			(ortstmt.ortstmt.STMT_user_INSERT));
  548 
  549 		parms.push(v1);
  550 		parms.push(v2);
  551 		parms.push(bcrypt.hashSync(v3, bcrypt.genSaltSync()));
  552 		parms.push(v4);
  553 		parms.push(v5);
  554 		parms.push(v6);
  555 
  556 		try {
  557 			info = stmt.run(parms);
  558 		} catch (er) {
  559 			return BigInt(-1);
  560 		}
  561 
  562 		return BigInt(info.lastInsertRowid);
  563 	}
  564 
  565 	/**
  566 	 * Create a function that searches for users by a given
  567 	 *     name; and, when found, invokes a callback function
  568 	 *     provided the user structure.
  569 	 * This callback function is called during an implicit transaction: 
  570 	 * thus, it should not invoke any database modifications or risk 
  571 	 * deadlock.
  572 	 * @param v1 name
  573 	 * @param cb Callback with retrieved data.
  574 	 */
  575 	db_user_iterate_by_name_eq(v1: string,
  576 		cb: (res: ortns.user) => void): void
  577 	{
  578 		const parms: any[] = [];
  579 		const stmt: Database.Statement =
  580 			this.#o.db.prepare(ortstmt.stmtBuilder
  581 			(ortstmt.ortstmt.STMT_user_BY_SEARCH_0));
  582 		stmt.raw(true);
  583 
  584 		parms.push(v1);
  585 
  586 		for (const cols of stmt.iterate(parms)) {
  587 			const obj: ortns.userData =
  588 				this.db_user_fill({row: <any>cols, pos: 0});
  589 			cb(new ortns.user(this.#role, obj));
  590 		}
  591 	}
  592 
  593 	/**
  594 	 * Search for a unique user with their e-mail and
  595 	 *     password.
  596 	 *     This is a quick way to verify that a user has entered
  597 	 *     the correct password for logging in.
  598 	 * @param v1 email
  599 	 * @param v2 hash (hashed password)
  600 	 * @return Result or null if no results found.
  601 	 */
  602 	db_user_get_creds(v1: string, v2: string): ortns.user|null
  603 	{
  604 		const parms: any[] = [];
  605 		const stmt: Database.Statement =
  606 			this.#o.db.prepare(ortstmt.stmtBuilder
  607 			(ortstmt.ortstmt.STMT_user_BY_SEARCH_1));
  608 		stmt.raw(true);
  609 
  610 		parms.push(v1);
  611 		parms.push(bcrypt.hashSync(v2, bcrypt.genSaltSync()));
  612 
  613 		const cols: any = stmt.get(parms);
  614 
  615 		if (typeof cols === 'undefined')
  616 			return null;
  617 		const obj: ortns.userData = 
  618 			this.db_user_fill({row: <any[]>cols, pos: 0});
  619 		return new ortns.user(this.#role, obj);
  620 	}
  621 
  622 	/**
  623 	 * Lookup by unique identifier.
  624 	 * @param v1 uid
  625 	 * @return Result or null if no results found.
  626 	 */
  627 	db_user_get_by_uid_eq(v1: BigInt): ortns.user|null
  628 	{
  629 		const parms: any[] = [];
  630 		const stmt: Database.Statement =
  631 			this.#o.db.prepare(ortstmt.stmtBuilder
  632 			(ortstmt.ortstmt.STMT_user_BY_SEARCH_2));
  633 		stmt.raw(true);
  634 
  635 		parms.push(v1);
  636 
  637 		const cols: any = stmt.get(parms);
  638 
  639 		if (typeof cols === 'undefined')
  640 			return null;
  641 		const obj: ortns.userData = 
  642 			this.db_user_fill({row: <any[]>cols, pos: 0});
  643 		return new ortns.user(this.#role, obj);
  644 	}
  645 
  646 	/**
  647 	 * 
  648 	 */
  649 	db_user_delete(): void
  650 	{
  651 		const parms: any[] = [];
  652 		let info: Database.RunResult;
  653 		const stmt: Database.Statement =
  654 			this.#o.db.prepare(ortstmt.stmtBuilder
  655 			(ortstmt.ortstmt.STMT_user_DELETE_0));
  656 
  657 
  658 		stmt.run(parms);
  659 	}
  660 
  661 	/**
  662 	 * @param v1 update hash (hashed)
  663 	 * @param v2 uid (eq)
  664 	 * @return False on constraint violation, true on success.
  665 	 */
  666 	db_user_update_hash_set_by_uid_eq(v1: string, v2: BigInt): boolean
  667 	{
  668 		const parms: any[] = [];
  669 		let info: Database.RunResult;
  670 		const stmt: Database.Statement =
  671 			this.#o.db.prepare(ortstmt.stmtBuilder
  672 			(ortstmt.ortstmt.STMT_user_UPDATE_0));
  673 
  674 		parms.push(bcrypt.hashSync(v1, bcrypt.genSaltSync()));
  675 		parms.push(v2);
  676 
  677 		try {
  678 			info = stmt.run(parms);
  679 		} catch (er) {
  680 			return false;
  681 		}
  682 
  683 		return true;
  684 	}
  685 
  686 	/**
  687 	 * @param v1 update email
  688 	 * @param v2 uid (eq)
  689 	 * @return False on constraint violation, true on success.
  690 	 */
  691 	db_user_update_email_set_by_uid_eq(v1: string, v2: BigInt):
  692 		boolean
  693 	{
  694 		const parms: any[] = [];
  695 		let info: Database.RunResult;
  696 		const stmt: Database.Statement =
  697 			this.#o.db.prepare(ortstmt.stmtBuilder
  698 			(ortstmt.ortstmt.STMT_user_UPDATE_1));
  699 
  700 		parms.push(v1);
  701 		parms.push(v2);
  702 
  703 		try {
  704 			info = stmt.run(parms);
  705 		} catch (er) {
  706 			return false;
  707 		}
  708 
  709 		return true;
  710 	}
  711 
  712 	private db_session_fill(data: {row: any[], pos: number}):
  713 		ortns.sessionData
  714 	{
  715 		const obj: ortns.sessionData = {
  716 			/* A dummy value for now. */
  717 			'user': <ortns.userData>{},
  718 			'userid': <BigInt>data.row[data.pos + 0],
  719 			'token': <BigInt>data.row[data.pos + 1],
  720 			'mtime': <BigInt>data.row[data.pos + 2],
  721 			'id': <BigInt>data.row[data.pos + 3],
  722 		};
  723 		data.pos += 4;
  724 		obj.user = this.db_user_fill(data);
  725 		return obj;
  726 	}
  727 
  728 	/**
  729 	 * Insert a new row into the database. Only native (and non-rowid) 
  730 	 * fields may be set.
  731 	 * @param v1 userid
  732 	 * @param v2 token
  733 	 * @param v3 mtime
  734 	 * @return New row's identifier on success or <0 otherwise.
  735 	 */
  736 	db_session_insert(v1: BigInt, v2: BigInt, v3: BigInt): BigInt
  737 	{
  738 		const parms: any[] = [];
  739 		let info: Database.RunResult;
  740 		const stmt: Database.Statement =
  741 			this.#o.db.prepare(ortstmt.stmtBuilder
  742 			(ortstmt.ortstmt.STMT_session_INSERT));
  743 
  744 		parms.push(v1);
  745 		parms.push(v2);
  746 		parms.push(v3);
  747 
  748 		try {
  749 			info = stmt.run(parms);
  750 		} catch (er) {
  751 			return BigInt(-1);
  752 		}
  753 
  754 		return BigInt(info.lastInsertRowid);
  755 	}
  756 
  757 	/**
  758 	 * Search for company's logged-in users.
  759 	 * This callback function is called during an implicit transaction: 
  760 	 * thus, it should not invoke any database modifications or risk 
  761 	 * deadlock.
  762 	 * @param v1 user.company.name
  763 	 * @param v2 mtime
  764 	 * @param cb Callback with retrieved data.
  765 	 */
  766 	db_session_iterate_foo(v1: string, v2: BigInt,
  767 		cb: (res: ortns.session) => void): void
  768 	{
  769 		const parms: any[] = [];
  770 		const stmt: Database.Statement =
  771 			this.#o.db.prepare(ortstmt.stmtBuilder
  772 			(ortstmt.ortstmt.STMT_session_BY_SEARCH_0));
  773 		stmt.raw(true);
  774 
  775 		parms.push(v1);
  776 		parms.push(v2);
  777 
  778 		for (const cols of stmt.iterate(parms)) {
  779 			const obj: ortns.sessionData =
  780 				this.db_session_fill({row: <any>cols, pos: 0});
  781 			cb(new ortns.session(this.#role, obj));
  782 		}
  783 	}
  784 
  785 	/**
  786 	 * @param v1 id (eq)
  787 	 * 
  788 	 */
  789 	db_session_delete_by_id_eq(v1: BigInt): void
  790 	{
  791 		const parms: any[] = [];
  792 		let info: Database.RunResult;
  793 		const stmt: Database.Statement =
  794 			this.#o.db.prepare(ortstmt.stmtBuilder
  795 			(ortstmt.ortstmt.STMT_session_DELETE_0));
  796 
  797 		parms.push(v1);
  798 
  799 		stmt.run(parms);
  800 	}
  801 }
  802 
  803 /**
  804  * Instance an application-wide context. This should only be called once 
  805  * per server, with the {@link ortdb.connect} method used for sequences 
  806  * of operations.
  807  */
  808 export function ort(dbname: string): ortdb
  809 {
  810 	return new ortdb(dbname);
  811 }