mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
5ef889addd
Summary: This moves enough server material into core to run a home server. The data engine is not yet incorporated (though in manual testing it works when ported). Test Plan: existing tests pass Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2552
91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
import {DatabaseType} from 'typeorm';
|
|
|
|
/**
|
|
*
|
|
* Generates an expression to simulate postgres's bit_or
|
|
* aggregate function in sqlite. The expression is verbose,
|
|
* and has a term for each bit in the permission bitmap,
|
|
* but this seems ok since sqlite is only used in the dev
|
|
* environment.
|
|
* @param column: the sql column to aggregate
|
|
* @param bits: the maximum number of bits to consider
|
|
*
|
|
*/
|
|
export function sqliteBitOr(column: string, bits: number): string {
|
|
const parts: string[] = [];
|
|
let mask: number = 1;
|
|
for (let b = 0; b < bits; b++) {
|
|
parts.push(`((sum(${column}&${mask})>0)<<${b})`);
|
|
mask *= 2;
|
|
}
|
|
return `(${parts.join('+')})`;
|
|
}
|
|
|
|
/**
|
|
* Generates an expression to aggregate the named column
|
|
* by taking the bitwise-or of all the values it takes on.
|
|
* @param dbType: the type of database (sqlite and postgres are supported)
|
|
* @param column: the sql column to aggregate
|
|
* @param bits: the maximum number of bits to consider (used for sqlite variant)
|
|
*/
|
|
export function bitOr(dbType: DatabaseType, column: string, bits: number): string {
|
|
switch (dbType) {
|
|
case 'postgres':
|
|
return `bit_or(${column})`;
|
|
case 'sqlite':
|
|
return sqliteBitOr(column, bits);
|
|
default:
|
|
throw new Error(`bitOr not implemented for ${dbType}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a json value returned by the database into a javascript
|
|
* object. For postgres, the value is already unpacked, but for sqlite
|
|
* it is a string.
|
|
*/
|
|
export function readJson(dbType: DatabaseType, selection: any) {
|
|
switch (dbType) {
|
|
case 'postgres':
|
|
return selection;
|
|
case 'sqlite':
|
|
return JSON.parse(selection);
|
|
default:
|
|
throw new Error(`readJson not implemented for ${dbType}`);
|
|
}
|
|
}
|
|
|
|
export function now(dbType: DatabaseType) {
|
|
switch (dbType) {
|
|
case 'postgres':
|
|
return 'now()';
|
|
case 'sqlite':
|
|
return "datetime('now')";
|
|
default:
|
|
throw new Error(`now not implemented for ${dbType}`);
|
|
}
|
|
}
|
|
|
|
// Understands strings like: "-30 days" or "1 year"
|
|
export function fromNow(dbType: DatabaseType, relative: string) {
|
|
switch (dbType) {
|
|
case 'postgres':
|
|
return `(now() + interval '${relative}')`;
|
|
case 'sqlite':
|
|
return `datetime('now','${relative}')`;
|
|
default:
|
|
throw new Error(`fromNow not implemented for ${dbType}`);
|
|
}
|
|
}
|
|
|
|
export function datetime(dbType: DatabaseType) {
|
|
switch (dbType) {
|
|
case 'postgres':
|
|
return 'timestamp with time zone';
|
|
case 'sqlite':
|
|
return "datetime";
|
|
default:
|
|
throw new Error(`now not implemented for ${dbType}`);
|
|
}
|
|
}
|