mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) move home server into core
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
This commit is contained in:
72
app/common/Formula.ts
Normal file
72
app/common/Formula.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
*
|
||||
* This represents a formula supported under SQL for on-demand tables. This is currently
|
||||
* a very small subset of the formulas supported by the data engine for regular tables.
|
||||
*
|
||||
* The following kinds of formula are supported:
|
||||
* $refColId.colId [where colId is not itself a formula]
|
||||
* $colId [where colId is not itself a formula]
|
||||
* NNN [a non-negative integer]
|
||||
* TODO: support a broader range of formula, by adding a parser or reusing Python parser.
|
||||
* An argument for reusing Python parser: wwe already do substantial parsing of the formula code.
|
||||
* E.g. Python does such amazing things as handle updating the formula when any of the columns
|
||||
* referred to in Foo.lookup(bar=$baz).blah get updated.
|
||||
*
|
||||
*/
|
||||
export type Formula = LiteralNumberFormula | ColumnFormula | ForeignColumnFormula | FormulaError;
|
||||
|
||||
// A simple copy of another column. E.g. "$Person"
|
||||
export interface ColumnFormula {
|
||||
kind: 'column';
|
||||
colId: string;
|
||||
}
|
||||
|
||||
// A copy of a column in another table (via a reference column). E.g. "$Person.FirstName"
|
||||
export interface ForeignColumnFormula {
|
||||
kind: 'foreignColumn';
|
||||
colId: string;
|
||||
refColId: string;
|
||||
}
|
||||
|
||||
export interface LiteralNumberFormula {
|
||||
kind: 'literalNumber';
|
||||
value: number;
|
||||
}
|
||||
|
||||
// A formula that couldn't be parsed.
|
||||
export interface FormulaError {
|
||||
kind: 'error';
|
||||
msg: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to a parsed formula. Regexes are adequate for the very few
|
||||
* supported formulas, but once the syntax is at all flexible a proper parser will
|
||||
* be needed. In principle, it might make sense to support python syntax, for
|
||||
* compatibility with the data engine, but compatibility in corner cases will be
|
||||
* fiddly given underlying differences between sqlite and python.
|
||||
*/
|
||||
export function parseFormula(txt: string): Formula {
|
||||
// Formula of form: $x.y
|
||||
let m = txt.match(/^\$([a-z]\w*)\.([a-z]\w*)$/i);
|
||||
if (m) {
|
||||
return {kind: 'foreignColumn', refColId: m[1], colId: m[2]};
|
||||
}
|
||||
|
||||
// Formula of form: $x
|
||||
m = txt.match(/^\$([a-z][a-z_0-9]*)$/i);
|
||||
if (m) {
|
||||
return {kind: 'column', colId: m[1]};
|
||||
}
|
||||
|
||||
// Formula of form: NNN
|
||||
m = txt.match(/^[0-9]+$/);
|
||||
if (m) {
|
||||
const value = parseInt(txt, 10);
|
||||
if (isNaN(value)) { return {kind: 'error', msg: 'Cannot parse integer'}; }
|
||||
return {kind: 'literalNumber', value};
|
||||
}
|
||||
|
||||
// Everything else is an error.
|
||||
return {kind: 'error', msg: 'Formula not supported'};
|
||||
}
|
||||
Reference in New Issue
Block a user