namespace _sindri.outputs.database.postgresql { /** */ function value_encode( value : any ) : string { if (value === null) { return "NULL"; } else { switch (typeof(value)) { case "boolean": { return (value ? "TRUE" : "FALSE"); break; } case "number": { return value.toString(); break; } case "string": { return ("'" + value + "'"); break; } default: { throw (new Error("unhandled")); break; } } } } /** */ export function render( input_data ) : string { return ( input_data.domains .map( (domain) => lib_plankton.string.coin( "CREATE TABLE\n\t{{name}}(\n{{entries}}\n\t)\n;\n{{comments}}", { "name": domain.name, "entries": ( ( [] // key field .concat( (domain.key_field === null) ? [] : lib_plankton.string.coin( "{{name}} {{parameters}}", { "name": ('"' + domain.key_field.name + '"'), "parameters": ( [ "SERIAL", ] .join(" ") ), } ) ) // data fields .concat( domain.data_fields .map( (data_field) => lib_plankton.string.coin( "{{name}} {{parameters}}", { "name": ('"' + data_field.name + '"'), "parameters": ( ( // type [ { "boolean": "BOOLEAN", "integer": "INTEGER", "string_short": "VARCHAR(63)", "string_medium": "VARCHAR(255)", "string_long": "TEXT", }[data_field.type], ] // nullability .concat( data_field.nullable ? [] : ["NOT NULL"] ) // default .concat( (data_field.default === undefined) ? [] : [ lib_plankton.string.coin( "DEFAULT {{value}}", { "value": value_encode(data_field.default), } ), ] ) ) .join(" ") ) } ) ) ) // constraints .concat( domain["constraints"] .concat( (domain.key_field === null) ? [] : [ { "kind": "unique", "parameters": { "fields": [ domain.key_field.name, ] } }, ] ) .map( (constraint) => { switch (constraint.kind) { default: { throw (new Error("unhandled constraint kind: " + constraint.kind)); break; } case "foreign_key": { return lib_plankton.string.coin( "FOREIGN KEY ({{fields}}) REFERENCES {{reference_name}}({{reference_fields}})", { "fields": ( constraint.parameters["fields"] .map(x => ('"' + x + '"')) .join(",") ), "reference_name": ('"' + constraint.parameters["reference"]["name"] + '"'), "reference_fields": ( constraint.parameters["reference"]["fields"] .map(x => ('"' + x + '"')) .join(",") ), } ); break; } case "unique": { return lib_plankton.string.coin( "UNIQUE ({{fields}})", { "fields": ( constraint.parameters["fields"] .map(x => ('"' + x + '"')) .join(",") ), } ); break; } } } ) ) ) .map(x => ("\t\t" + x)) .join(",\n") ), "comments": ( ( [] .concat( (! (domain.description === null)) ? [ { "kind": "TABLE", "subject": domain.name, "value": domain.description, } ] : [] ) .concat( ( (! (domain.key_field === null)) && (! (domain.key_field.description === null)) ) ? [ { "kind": "COLUMN", "subject": (domain.name + "." + domain.key_field.name), "value": domain.key_field.description, } ] : [] ) .concat( domain.data_fields .filter( data_field => (! (data_field.description === null)) ) .map( data_field => ({ "kind": "COLUMN", "subject": (domain.name + "." + data_field.name), "value": data_field.description, }) ) ) ) .map( entry => lib_plankton.string.coin( "COMMENT ON {{kind}} {{subject}} IS '{{value}}';", { "kind": entry.kind, "subject": entry.subject, "value": entry.value, } ) ) .join("\n") ), } ) ) .map(x => (x + "\n")) .join("\n") ); } } /** */ _sindri.add_output( _sindri.enum_realm.database, "postgresql", { "render": (x) => Promise.resolve(_sindri.outputs.database.postgresql.render(x)), } );