miniorm
Version:
A lightweight, minimal TypeScript ORM & query‑builder for MySQL, PostgreSQL and SQLite
150 lines (149 loc) • 7.72 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeclarativeTableBuilder = void 0;
const core_1 = require("../core");
const types_1 = require("../types");
class DeclarativeTableBuilder {
constructor(tableName, dbName) {
this.tableName = '';
this.columns = [];
this.tables = {};
this.dbName = dbName;
this.tableName = tableName;
this.initDbNamespace();
this.initTableNamespace();
}
initDbNamespace() {
if (!this.tables[this.dbName])
this.tables[this.dbName] = {};
}
initTableNamespace() {
if (!this.tables[this.dbName][this.tableName])
this.tables[this.dbName][this.tableName] = [];
// this.dbs = MiniOrm.dbs
}
column(column) {
this.columns.push(column);
this.tables[this.dbName][this.tableName].push(column);
return this;
}
set(tableName, dbName) {
// this.tables[this.dbName][this.tableName] = this.columns
this.columns = [];
this.dbName = typeof dbName == 'string' ? dbName : this.dbName;
this.tableName = tableName;
this.initDbNamespace();
this.initTableNamespace();
return this;
}
static checkTableExists(db, dbType, tableName) {
return new Promise((resolve, reject) => {
if (dbType === 'mysql') {
db.query(`SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ?`, [tableName], (err, results) => {
if (err)
return reject(err);
resolve(results.length >= 1);
});
}
else if (dbType === 'sqlite') {
db.get(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`, [tableName], (err, row) => {
if (err)
return reject(err);
resolve(!!row);
});
}
else if (dbType === 'postgresql') {
db.query(`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1`, [tableName], (err, results) => {
if (err)
return reject(err);
resolve(results.rows.length >= 1);
});
}
else {
reject(new Error('Unsupported DB type'));
}
});
}
build() {
return __awaiter(this, void 0, void 0, function* () {
const dbPromises = Object.entries(this.tables).map((_a) => __awaiter(this, [_a], void 0, function* ([dbName, tables]) {
const dbType = core_1.MiniOrm.dbs[dbName].config.type;
if (dbType.startsWith('typeorm'))
return;
const db = core_1.MiniOrm.dbs[dbName].db, tablePromises = Object.entries(tables).map((_a) => __awaiter(this, [_a], void 0, function* ([tableName, columns]) {
const if_exists = yield DeclarativeTableBuilder.checkTableExists(db, dbType, tableName);
if (if_exists)
return;
const columnDefinitions = columns.map(column => {
column.type = column.primaryKey ? 'INTEGER' : column.type;
let column_length = column.length != undefined
? column.length
: (column.type == types_1.DatabaseColumnType.VARCHAR
? (column.unique ? 191 : 255)
: column.length);
if (column_length && column.unique && column_length > 191)
column_length = 191;
let columnDefinition = `${column.name} ${column.primaryKey ? 'INTEGER' : column.type}${column_length == undefined && column.type != 'VARCHAR'
? ''
: `(${column_length})`}`;
if (column.enum) {
const enums = column.enum.map(e => typeof e === 'string' ? `'${e}'` : e).join(', ');
columnDefinition += dbType == 'sqlite'
? ` CHECK( ${column.name} IN (${enums}) )`
: `(${enums})`;
if (!column.notNull)
columnDefinition += ' NOT NULL';
if (!column.defaultValue)
columnDefinition += ` DEFAULT '${column.enum[0]}'`;
}
if (column.primaryKey) {
columnDefinition += ' PRIMARY KEY';
if (column.type.toUpperCase() === 'INTEGER' && column.autoIncrement !== false) {
const autoIncrementSyntax = dbType == 'sqlite'
? 'AUTOINCREMENT'
: dbType == 'mysql'
? 'AUTO_INCREMENT'
: 'GENERATED ALWAYS AS IDENTITY';
columnDefinition += ` ${autoIncrementSyntax}`;
}
}
if (column.notNull)
columnDefinition += ' NOT NULL';
if (column.unique)
columnDefinition += ' UNIQUE';
if (column.defaultValue !== undefined) {
if (typeof column.defaultValue === 'boolean')
columnDefinition += ` DEFAULT ${column.defaultValue ? '1' : '0'}`;
else {
const defaultValueStr = typeof column.defaultValue === 'string'
? `'${column.defaultValue}'`
: column.defaultValue;
columnDefinition += ` DEFAULT ${defaultValueStr}`;
}
}
if (column.check !== undefined)
columnDefinition += ` CHECK (${column.name + column.check})`;
if (column.collate)
columnDefinition += ` COLLATE ${column.collate}`;
return columnDefinition;
});
const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columnDefinitions.join(', ')})`;
yield core_1.MiniOrm.runQuery(dbName, query, []);
console.log(`${dbType.toUpperCase()} Table '${tableName}' is ready to use. Added Database '${dbName}'`);
}));
yield Promise.all(tablePromises);
}));
yield Promise.all(dbPromises);
});
}
}
exports.DeclarativeTableBuilder = DeclarativeTableBuilder;