@abaplint/transpiler
Version:
112 lines • 4.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatabaseSetup = void 0;
const abaplint = require("@abaplint/core");
const sqlite_database_schema_1 = require("./schema_generation/sqlite_database_schema");
const pg_database_schema_1 = require("./schema_generation/pg_database_schema");
const snowflake_database_schema_1 = require("./schema_generation/snowflake_database_schema");
/////////////////////////
// NOTES
/////////////////////////
// Postgres is case sensitive, so all column names should be lower case
// Sqlite escapes field names with single qoute, postgres with double
class DatabaseSetup {
constructor(reg) {
this.reg = reg;
}
run(options) {
return {
schemas: {
sqlite: this.driver(new sqlite_database_schema_1.SQLiteDatabaseSchema(this.reg)),
hdb: ["todo"],
pg: this.driver(new pg_database_schema_1.PGDatabaseSchema(this.reg)),
snowflake: this.driver(new snowflake_database_schema_1.SnowflakeDatabaseSchema(this.reg)),
},
insert: this.buildInsert(options),
};
}
////////////////////
driver(schemaGenerator) {
const statements = [];
// CREATE TABLEs
for (const obj of this.reg.getObjects()) {
if (obj instanceof abaplint.Objects.Table
&& obj.getTableCategory() === abaplint.Objects.TableCategory.Transparent) {
statements.push(schemaGenerator.buildTABL(obj).trim());
}
}
// CREATE VIEWs after TABLEs
// todo: what if the view is based on another view?
for (const obj of this.reg.getObjects()) {
if (obj instanceof abaplint.Objects.View) {
statements.push(schemaGenerator.buildVIEW(obj).trim());
}
}
return statements;
}
buildInsert(options) {
// note: avoid hitting maximum statement size by splitting into multiple statements
const insert = [];
// INSERT data
for (const obj of this.reg.getObjects()) {
if (obj instanceof abaplint.Objects.MessageClass) {
insert.push(...this.insertT100(obj));
}
else if (obj instanceof abaplint.Objects.Class
|| obj instanceof abaplint.Objects.Interface) {
if (options?.skipReposrc !== true) {
insert.push(this.insertREPOSRC(obj));
}
}
}
insert.push(this.insertT000());
return insert;
}
insertREPOSRC(obj) {
if (this.reg.getObject("TABL", "REPOSRC") === undefined) {
return "";
}
const name = obj.getName().toUpperCase();
const raw = obj.getMainABAPFile()?.getRaw();
if (raw === undefined) {
return "";
}
return `INSERT INTO reposrc ('PROGNAME', 'DATA') VALUES ('${name.padEnd(40, " ")}', '${this.escape(raw)}');`;
}
insertT000() {
const tabl = this.reg.getObject("TABL", "T000");
if (tabl === undefined) {
return "";
}
const type = tabl.parseType(this.reg);
if (type instanceof abaplint.BasicTypes.StructureType && type.getComponents().length >= 3) {
// todo, this should take the client number from the settings
return `INSERT INTO t000 ('mandt', 'cccategory', 'ccnocliind') VALUES ('123', '', '');`;
}
else {
return "";
}
}
insertT100(msag) {
// ignore if T100 is unknown
const obj = this.reg.getObject("TABL", "T100");
if (obj === undefined) {
return [];
}
const ret = [];
for (const m of msag.getMessages()) {
ret.push(`INSERT INTO "t100" ("sprsl", "arbgb", "msgnr", "text") VALUES ('E', '${msag.getName().padEnd(20, " ")}', '${m.getNumber()}', '${this.escape(m.getMessage().padEnd(73, " "))}');`);
}
return ret;
}
escape(value) {
let ret = value.replace(/\'/g, "''");
// statements are inside a javascript string stemplate
ret = ret.replace(/\\/g, "\\\\");
ret = ret.replace(/`/g, "\\`");
ret = ret.replace(/\${/g, "\\${");
return ret;
}
}
exports.DatabaseSetup = DatabaseSetup;
//# sourceMappingURL=index.js.map