@bunnykit/orm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +904 -0
- package/dist/bin/bunny.d.ts +2 -0
- package/dist/bin/bunny.js +108 -0
- package/dist/src/connection/Connection.d.ts +13 -0
- package/dist/src/connection/Connection.js +49 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +18 -0
- package/dist/src/migration/Migration.d.ts +4 -0
- package/dist/src/migration/Migration.js +2 -0
- package/dist/src/migration/MigrationCreator.d.ts +5 -0
- package/dist/src/migration/MigrationCreator.js +39 -0
- package/dist/src/migration/Migrator.d.ts +21 -0
- package/dist/src/migration/Migrator.js +137 -0
- package/dist/src/model/BelongsToMany.d.ts +27 -0
- package/dist/src/model/BelongsToMany.js +118 -0
- package/dist/src/model/Model.d.ts +166 -0
- package/dist/src/model/Model.js +763 -0
- package/dist/src/model/MorphMap.d.ts +7 -0
- package/dist/src/model/MorphMap.js +12 -0
- package/dist/src/model/MorphRelations.d.ts +81 -0
- package/dist/src/model/MorphRelations.js +296 -0
- package/dist/src/model/Observer.d.ts +19 -0
- package/dist/src/model/Observer.js +21 -0
- package/dist/src/query/Builder.d.ts +106 -0
- package/dist/src/query/Builder.js +466 -0
- package/dist/src/schema/Blueprint.d.ts +66 -0
- package/dist/src/schema/Blueprint.js +200 -0
- package/dist/src/schema/Schema.d.ts +16 -0
- package/dist/src/schema/Schema.js +135 -0
- package/dist/src/schema/grammars/Grammar.d.ts +26 -0
- package/dist/src/schema/grammars/Grammar.js +95 -0
- package/dist/src/schema/grammars/MySqlGrammar.d.ts +18 -0
- package/dist/src/schema/grammars/MySqlGrammar.js +96 -0
- package/dist/src/schema/grammars/PostgresGrammar.d.ts +16 -0
- package/dist/src/schema/grammars/PostgresGrammar.js +88 -0
- package/dist/src/schema/grammars/SQLiteGrammar.d.ts +16 -0
- package/dist/src/schema/grammars/SQLiteGrammar.js +108 -0
- package/dist/src/typegen/TypeGenerator.d.ts +29 -0
- package/dist/src/typegen/TypeGenerator.js +171 -0
- package/dist/src/typegen/TypeMapper.d.ts +4 -0
- package/dist/src/typegen/TypeMapper.js +27 -0
- package/dist/src/types/index.d.ts +53 -0
- package/dist/src/types/index.js +1 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.js +6 -0
- package/package.json +62 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
export class ForeignKeyBuilder {
|
|
2
|
+
fk;
|
|
3
|
+
blueprint;
|
|
4
|
+
constructor(blueprint, columns, name) {
|
|
5
|
+
this.blueprint = blueprint;
|
|
6
|
+
this.fk = { name, columns, references: [], onTable: "" };
|
|
7
|
+
blueprint.foreignKeys.push(this.fk);
|
|
8
|
+
}
|
|
9
|
+
references(columns) {
|
|
10
|
+
this.fk.references = Array.isArray(columns) ? columns : [columns];
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
on(table) {
|
|
14
|
+
this.fk.onTable = table;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
onDelete(action) {
|
|
18
|
+
this.fk.onDelete = action;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
onUpdate(action) {
|
|
22
|
+
this.fk.onUpdate = action;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class Blueprint {
|
|
27
|
+
table;
|
|
28
|
+
columns = [];
|
|
29
|
+
indexes = [];
|
|
30
|
+
foreignKeys = [];
|
|
31
|
+
commands = [];
|
|
32
|
+
currentColumn;
|
|
33
|
+
constructor(table) {
|
|
34
|
+
this.table = table;
|
|
35
|
+
}
|
|
36
|
+
addColumn(type, name, length) {
|
|
37
|
+
const column = {
|
|
38
|
+
name,
|
|
39
|
+
type,
|
|
40
|
+
length,
|
|
41
|
+
nullable: false,
|
|
42
|
+
autoIncrement: false,
|
|
43
|
+
primary: false,
|
|
44
|
+
unique: false,
|
|
45
|
+
index: false,
|
|
46
|
+
unsigned: false,
|
|
47
|
+
};
|
|
48
|
+
this.columns.push(column);
|
|
49
|
+
this.currentColumn = column;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
increments(name = "id") {
|
|
53
|
+
const col = this.addColumn("integer", name);
|
|
54
|
+
col.currentColumn.autoIncrement = true;
|
|
55
|
+
col.currentColumn.primary = true;
|
|
56
|
+
col.currentColumn.unsigned = true;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
bigIncrements(name = "id") {
|
|
60
|
+
const col = this.addColumn("bigInteger", name);
|
|
61
|
+
col.currentColumn.autoIncrement = true;
|
|
62
|
+
col.currentColumn.primary = true;
|
|
63
|
+
col.currentColumn.unsigned = true;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
string(name, length = 255) {
|
|
67
|
+
return this.addColumn("string", name, length);
|
|
68
|
+
}
|
|
69
|
+
text(name) {
|
|
70
|
+
return this.addColumn("text", name);
|
|
71
|
+
}
|
|
72
|
+
integer(name) {
|
|
73
|
+
return this.addColumn("integer", name);
|
|
74
|
+
}
|
|
75
|
+
bigInteger(name) {
|
|
76
|
+
return this.addColumn("bigInteger", name);
|
|
77
|
+
}
|
|
78
|
+
smallInteger(name) {
|
|
79
|
+
return this.addColumn("smallInteger", name);
|
|
80
|
+
}
|
|
81
|
+
tinyInteger(name) {
|
|
82
|
+
return this.addColumn("tinyInteger", name);
|
|
83
|
+
}
|
|
84
|
+
float(name, precision = 8, scale = 2) {
|
|
85
|
+
this.addColumn("float", name);
|
|
86
|
+
this.currentColumn.precision = precision;
|
|
87
|
+
this.currentColumn.scale = scale;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
double(name, precision = 8, scale = 2) {
|
|
91
|
+
this.addColumn("double", name);
|
|
92
|
+
this.currentColumn.precision = precision;
|
|
93
|
+
this.currentColumn.scale = scale;
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
decimal(name, precision = 8, scale = 2) {
|
|
97
|
+
this.addColumn("decimal", name);
|
|
98
|
+
this.currentColumn.precision = precision;
|
|
99
|
+
this.currentColumn.scale = scale;
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
boolean(name) {
|
|
103
|
+
return this.addColumn("boolean", name);
|
|
104
|
+
}
|
|
105
|
+
date(name) {
|
|
106
|
+
return this.addColumn("date", name);
|
|
107
|
+
}
|
|
108
|
+
dateTime(name) {
|
|
109
|
+
return this.addColumn("dateTime", name);
|
|
110
|
+
}
|
|
111
|
+
time(name) {
|
|
112
|
+
return this.addColumn("time", name);
|
|
113
|
+
}
|
|
114
|
+
timestamp(name) {
|
|
115
|
+
return this.addColumn("timestamp", name);
|
|
116
|
+
}
|
|
117
|
+
json(name) {
|
|
118
|
+
return this.addColumn("json", name);
|
|
119
|
+
}
|
|
120
|
+
jsonb(name) {
|
|
121
|
+
return this.addColumn("jsonb", name);
|
|
122
|
+
}
|
|
123
|
+
binary(name) {
|
|
124
|
+
return this.addColumn("binary", name);
|
|
125
|
+
}
|
|
126
|
+
uuid(name) {
|
|
127
|
+
return this.addColumn("uuid", name);
|
|
128
|
+
}
|
|
129
|
+
enum(name, values) {
|
|
130
|
+
this.addColumn("enum", name);
|
|
131
|
+
this.currentColumn.values = values;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
nullable() {
|
|
135
|
+
if (this.currentColumn)
|
|
136
|
+
this.currentColumn.nullable = true;
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
default(value) {
|
|
140
|
+
if (this.currentColumn)
|
|
141
|
+
this.currentColumn.default = value;
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
unique() {
|
|
145
|
+
if (this.currentColumn) {
|
|
146
|
+
this.currentColumn.unique = true;
|
|
147
|
+
}
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
index() {
|
|
151
|
+
if (this.currentColumn) {
|
|
152
|
+
this.currentColumn.index = true;
|
|
153
|
+
}
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
primary() {
|
|
157
|
+
if (this.currentColumn) {
|
|
158
|
+
this.currentColumn.primary = true;
|
|
159
|
+
}
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
unsigned() {
|
|
163
|
+
if (this.currentColumn) {
|
|
164
|
+
this.currentColumn.unsigned = true;
|
|
165
|
+
}
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
comment(text) {
|
|
169
|
+
if (this.currentColumn) {
|
|
170
|
+
this.currentColumn.comment = text;
|
|
171
|
+
}
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
timestamps() {
|
|
175
|
+
this.timestamp("created_at").nullable();
|
|
176
|
+
this.timestamp("updated_at").nullable();
|
|
177
|
+
}
|
|
178
|
+
softDeletes() {
|
|
179
|
+
this.timestamp("deleted_at").nullable();
|
|
180
|
+
}
|
|
181
|
+
foreign(columns, name) {
|
|
182
|
+
const cols = Array.isArray(columns) ? columns : [columns];
|
|
183
|
+
return new ForeignKeyBuilder(this, cols, name);
|
|
184
|
+
}
|
|
185
|
+
dropColumn(column) {
|
|
186
|
+
this.commands.push({ name: "dropColumn", parameters: { column: Array.isArray(column) ? column : [column] } });
|
|
187
|
+
}
|
|
188
|
+
renameColumn(from, to) {
|
|
189
|
+
this.commands.push({ name: "renameColumn", parameters: { from, to } });
|
|
190
|
+
}
|
|
191
|
+
dropIndex(name) {
|
|
192
|
+
this.commands.push({ name: "dropIndex", parameters: { name } });
|
|
193
|
+
}
|
|
194
|
+
dropUnique(name) {
|
|
195
|
+
this.commands.push({ name: "dropUnique", parameters: { name } });
|
|
196
|
+
}
|
|
197
|
+
dropForeign(name) {
|
|
198
|
+
this.commands.push({ name: "dropForeign", parameters: { name } });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Connection } from "../connection/Connection.js";
|
|
2
|
+
import { Blueprint } from "./Blueprint.js";
|
|
3
|
+
export declare class Schema {
|
|
4
|
+
static connection: Connection;
|
|
5
|
+
static setConnection(connection: Connection): void;
|
|
6
|
+
static getConnection(): Connection;
|
|
7
|
+
private static getGrammar;
|
|
8
|
+
static create(table: string, callback: (blueprint: Blueprint) => void): Promise<void>;
|
|
9
|
+
static createIfNotExists(table: string, callback: (blueprint: Blueprint) => void): Promise<void>;
|
|
10
|
+
static table(table: string, callback: (blueprint: Blueprint) => void): Promise<void>;
|
|
11
|
+
static drop(table: string): Promise<void>;
|
|
12
|
+
static dropIfExists(table: string): Promise<void>;
|
|
13
|
+
static rename(from: string, to: string): Promise<void>;
|
|
14
|
+
static hasTable(table: string): Promise<boolean>;
|
|
15
|
+
static hasColumn(table: string, column: string): Promise<boolean>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Blueprint } from "./Blueprint.js";
|
|
2
|
+
import { SQLiteGrammar } from "./grammars/SQLiteGrammar.js";
|
|
3
|
+
import { MySqlGrammar } from "./grammars/MySqlGrammar.js";
|
|
4
|
+
import { PostgresGrammar } from "./grammars/PostgresGrammar.js";
|
|
5
|
+
export class Schema {
|
|
6
|
+
static connection;
|
|
7
|
+
static setConnection(connection) {
|
|
8
|
+
this.connection = connection;
|
|
9
|
+
}
|
|
10
|
+
static getConnection() {
|
|
11
|
+
if (!this.connection) {
|
|
12
|
+
throw new Error("No database connection set.");
|
|
13
|
+
}
|
|
14
|
+
return this.connection;
|
|
15
|
+
}
|
|
16
|
+
static getGrammar() {
|
|
17
|
+
const driver = this.getConnection().getDriverName();
|
|
18
|
+
switch (driver) {
|
|
19
|
+
case "sqlite":
|
|
20
|
+
return new SQLiteGrammar();
|
|
21
|
+
case "mysql":
|
|
22
|
+
return new MySqlGrammar();
|
|
23
|
+
case "postgres":
|
|
24
|
+
return new PostgresGrammar();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
static async create(table, callback) {
|
|
28
|
+
const blueprint = new Blueprint(table);
|
|
29
|
+
callback(blueprint);
|
|
30
|
+
const grammar = this.getGrammar();
|
|
31
|
+
const sql = grammar.compileCreate(blueprint, table);
|
|
32
|
+
await this.getConnection().run(sql);
|
|
33
|
+
const indexes = grammar.compileIndexes(blueprint, table);
|
|
34
|
+
for (const indexSql of indexes) {
|
|
35
|
+
await this.getConnection().run(indexSql);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
static async createIfNotExists(table, callback) {
|
|
39
|
+
const blueprint = new Blueprint(table);
|
|
40
|
+
callback(blueprint);
|
|
41
|
+
const grammar = this.getGrammar();
|
|
42
|
+
const sql = grammar.compileCreateIfNotExists(blueprint, table);
|
|
43
|
+
await this.getConnection().run(sql);
|
|
44
|
+
const indexes = grammar.compileIndexes(blueprint, table);
|
|
45
|
+
for (const indexSql of indexes) {
|
|
46
|
+
await this.getConnection().run(indexSql);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
static async table(table, callback) {
|
|
50
|
+
const blueprint = new Blueprint(table);
|
|
51
|
+
callback(blueprint);
|
|
52
|
+
const grammar = this.getGrammar();
|
|
53
|
+
for (const command of blueprint.commands) {
|
|
54
|
+
if (command.name === "dropColumn") {
|
|
55
|
+
const sql = grammar.compileDropColumn(table, command.parameters.column);
|
|
56
|
+
if (Array.isArray(sql)) {
|
|
57
|
+
for (const s of sql)
|
|
58
|
+
await this.getConnection().run(s);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
await this.getConnection().run(sql);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (command.name === "renameColumn") {
|
|
65
|
+
const sql = grammar.compileColumnRename(table, command.parameters.from, command.parameters.to);
|
|
66
|
+
await this.getConnection().run(sql);
|
|
67
|
+
}
|
|
68
|
+
else if (command.name === "dropIndex") {
|
|
69
|
+
await this.getConnection().run(`DROP INDEX ${grammar.wrap(command.parameters.name)}`);
|
|
70
|
+
}
|
|
71
|
+
else if (command.name === "dropUnique") {
|
|
72
|
+
await this.getConnection().run(`DROP INDEX ${grammar.wrap(command.parameters.name)}`);
|
|
73
|
+
}
|
|
74
|
+
else if (command.name === "dropForeign") {
|
|
75
|
+
await this.getConnection().run(`ALTER TABLE ${grammar.wrap(table)} DROP CONSTRAINT ${grammar.wrap(command.parameters.name)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const addSqls = grammar.compileAdd(blueprint, table);
|
|
79
|
+
for (const sql of addSqls) {
|
|
80
|
+
await this.getConnection().run(sql);
|
|
81
|
+
}
|
|
82
|
+
const indexes = grammar.compileIndexes(blueprint, table);
|
|
83
|
+
for (const indexSql of indexes) {
|
|
84
|
+
await this.getConnection().run(indexSql);
|
|
85
|
+
}
|
|
86
|
+
const fks = grammar.compileForeignKeys(blueprint, table);
|
|
87
|
+
for (const fkSql of fks) {
|
|
88
|
+
await this.getConnection().run(fkSql);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
static async drop(table) {
|
|
92
|
+
const grammar = this.getGrammar();
|
|
93
|
+
await this.getConnection().run(grammar.compileDrop(table));
|
|
94
|
+
}
|
|
95
|
+
static async dropIfExists(table) {
|
|
96
|
+
const grammar = this.getGrammar();
|
|
97
|
+
await this.getConnection().run(grammar.compileDropIfExists(table));
|
|
98
|
+
}
|
|
99
|
+
static async rename(from, to) {
|
|
100
|
+
const grammar = this.getGrammar();
|
|
101
|
+
await this.getConnection().run(grammar.compileRename(from, to));
|
|
102
|
+
}
|
|
103
|
+
static async hasTable(table) {
|
|
104
|
+
const driver = this.getConnection().getDriverName();
|
|
105
|
+
let sql;
|
|
106
|
+
if (driver === "sqlite") {
|
|
107
|
+
sql = `SELECT name FROM sqlite_master WHERE type='table' AND name='${table}'`;
|
|
108
|
+
}
|
|
109
|
+
else if (driver === "mysql") {
|
|
110
|
+
sql = `SHOW TABLES LIKE '${table}'`;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
sql = `SELECT * FROM information_schema.tables WHERE table_name = '${table}'`;
|
|
114
|
+
}
|
|
115
|
+
const result = await this.getConnection().query(sql);
|
|
116
|
+
return result.length > 0;
|
|
117
|
+
}
|
|
118
|
+
static async hasColumn(table, column) {
|
|
119
|
+
const driver = this.getConnection().getDriverName();
|
|
120
|
+
let sql;
|
|
121
|
+
if (driver === "sqlite") {
|
|
122
|
+
sql = `PRAGMA table_info(${table})`;
|
|
123
|
+
const result = await this.getConnection().query(sql);
|
|
124
|
+
return result.some((row) => row.name === column);
|
|
125
|
+
}
|
|
126
|
+
else if (driver === "mysql") {
|
|
127
|
+
sql = `SHOW COLUMNS FROM ${table} LIKE '${column}'`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
sql = `SELECT column_name FROM information_schema.columns WHERE table_name = '${table}' AND column_name = '${column}'`;
|
|
131
|
+
}
|
|
132
|
+
const result = await this.getConnection().query(sql);
|
|
133
|
+
return result.length > 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Blueprint } from "../Blueprint.js";
|
|
2
|
+
import type { ColumnDefinition, IndexDefinition, ForeignKeyDefinition } from "../../types/index.js";
|
|
3
|
+
export declare abstract class Grammar {
|
|
4
|
+
protected wrappers: Record<string, string>;
|
|
5
|
+
wrap(value: string): string;
|
|
6
|
+
wrapArray(values: string[]): string[];
|
|
7
|
+
compileCreate(blueprint: Blueprint, table: string): string;
|
|
8
|
+
compileCreateIfNotExists(blueprint: Blueprint, table: string): string;
|
|
9
|
+
compileDrop(table: string): string;
|
|
10
|
+
compileDropIfExists(table: string): string;
|
|
11
|
+
compileRename(from: string, to: string): string;
|
|
12
|
+
compileAdd(blueprint: Blueprint, table: string): string[];
|
|
13
|
+
protected getColumns(blueprint: Blueprint): string[];
|
|
14
|
+
protected getColumn(_blueprint: Blueprint, column: ColumnDefinition): string;
|
|
15
|
+
protected abstract getType(column: ColumnDefinition): string;
|
|
16
|
+
protected modifyUnsigned(_column: ColumnDefinition): string;
|
|
17
|
+
protected modifyAutoIncrement(_column: ColumnDefinition): string;
|
|
18
|
+
protected modifyComment(_column: ColumnDefinition): string;
|
|
19
|
+
protected getDefaultValue(value: any): string;
|
|
20
|
+
compileIndexes(blueprint: Blueprint, table: string): string[];
|
|
21
|
+
protected compileIndex(table: string, index: IndexDefinition): string;
|
|
22
|
+
compileForeignKeys(blueprint: Blueprint, table: string): string[];
|
|
23
|
+
protected compileForeignKey(table: string, fk: ForeignKeyDefinition): string;
|
|
24
|
+
abstract compileColumnRename(table: string, from: string, to: string): string;
|
|
25
|
+
abstract compileDropColumn(table: string, columns: string[]): string | string[];
|
|
26
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export class Grammar {
|
|
2
|
+
wrappers = { prefix: '"', suffix: '"' };
|
|
3
|
+
wrap(value) {
|
|
4
|
+
if (value.includes(".")) {
|
|
5
|
+
return value.split(".").map((v) => this.wrap(v)).join(".");
|
|
6
|
+
}
|
|
7
|
+
const { prefix, suffix } = this.wrappers;
|
|
8
|
+
return `${prefix}${value}${suffix}`;
|
|
9
|
+
}
|
|
10
|
+
wrapArray(values) {
|
|
11
|
+
return values.map((v) => this.wrap(v));
|
|
12
|
+
}
|
|
13
|
+
compileCreate(blueprint, table) {
|
|
14
|
+
const columns = this.getColumns(blueprint).map((col) => ` ${col}`).join(",\n");
|
|
15
|
+
const sql = `CREATE TABLE ${this.wrap(table)} (\n${columns}\n)`;
|
|
16
|
+
return sql;
|
|
17
|
+
}
|
|
18
|
+
compileCreateIfNotExists(blueprint, table) {
|
|
19
|
+
const columns = this.getColumns(blueprint).map((col) => ` ${col}`).join(",\n");
|
|
20
|
+
return `CREATE TABLE IF NOT EXISTS ${this.wrap(table)} (\n${columns}\n)`;
|
|
21
|
+
}
|
|
22
|
+
compileDrop(table) {
|
|
23
|
+
return `DROP TABLE ${this.wrap(table)}`;
|
|
24
|
+
}
|
|
25
|
+
compileDropIfExists(table) {
|
|
26
|
+
return `DROP TABLE IF EXISTS ${this.wrap(table)}`;
|
|
27
|
+
}
|
|
28
|
+
compileRename(from, to) {
|
|
29
|
+
return `ALTER TABLE ${this.wrap(from)} RENAME TO ${this.wrap(to)}`;
|
|
30
|
+
}
|
|
31
|
+
compileAdd(blueprint, table) {
|
|
32
|
+
const columns = this.getColumns(blueprint);
|
|
33
|
+
return columns.map((col) => `ALTER TABLE ${this.wrap(table)} ADD COLUMN ${col}`);
|
|
34
|
+
}
|
|
35
|
+
getColumns(blueprint) {
|
|
36
|
+
return blueprint.columns.map((col) => this.getColumn(blueprint, col));
|
|
37
|
+
}
|
|
38
|
+
getColumn(_blueprint, column) {
|
|
39
|
+
let sql = `${this.wrap(column.name)} ${this.getType(column)}`;
|
|
40
|
+
if (column.unsigned)
|
|
41
|
+
sql += this.modifyUnsigned(column);
|
|
42
|
+
if (!column.nullable)
|
|
43
|
+
sql += " NOT NULL";
|
|
44
|
+
if (column.default !== undefined)
|
|
45
|
+
sql += ` DEFAULT ${this.getDefaultValue(column.default)}`;
|
|
46
|
+
if (column.autoIncrement)
|
|
47
|
+
sql += this.modifyAutoIncrement(column);
|
|
48
|
+
if (column.comment)
|
|
49
|
+
sql += this.modifyComment(column);
|
|
50
|
+
return sql;
|
|
51
|
+
}
|
|
52
|
+
modifyUnsigned(_column) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
modifyAutoIncrement(_column) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
modifyComment(_column) {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
getDefaultValue(value) {
|
|
62
|
+
if (value === null)
|
|
63
|
+
return "NULL";
|
|
64
|
+
if (typeof value === "boolean")
|
|
65
|
+
return value ? "1" : "0";
|
|
66
|
+
if (typeof value === "number")
|
|
67
|
+
return String(value);
|
|
68
|
+
if (typeof value === "string" && value.toUpperCase().includes("CURRENT_TIMESTAMP"))
|
|
69
|
+
return value;
|
|
70
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
71
|
+
}
|
|
72
|
+
compileIndexes(blueprint, table) {
|
|
73
|
+
const statements = [];
|
|
74
|
+
for (const index of blueprint.indexes) {
|
|
75
|
+
statements.push(this.compileIndex(table, index));
|
|
76
|
+
}
|
|
77
|
+
return statements;
|
|
78
|
+
}
|
|
79
|
+
compileIndex(table, index) {
|
|
80
|
+
const type = index.unique ? "UNIQUE INDEX" : "INDEX";
|
|
81
|
+
return `CREATE ${type} ${this.wrap(index.name)} ON ${this.wrap(table)} (${this.wrapArray(index.columns).join(", ")})`;
|
|
82
|
+
}
|
|
83
|
+
compileForeignKeys(blueprint, table) {
|
|
84
|
+
return blueprint.foreignKeys.map((fk) => this.compileForeignKey(table, fk));
|
|
85
|
+
}
|
|
86
|
+
compileForeignKey(table, fk) {
|
|
87
|
+
const sql = `ALTER TABLE ${this.wrap(table)} ADD CONSTRAINT ${this.wrap(fk.name || "")} FOREIGN KEY (${this.wrapArray(fk.columns).join(", ")}) REFERENCES ${this.wrap(fk.onTable)} (${this.wrapArray(fk.references).join(", ")})`;
|
|
88
|
+
let full = sql;
|
|
89
|
+
if (fk.onDelete)
|
|
90
|
+
full += ` ON DELETE ${fk.onDelete}`;
|
|
91
|
+
if (fk.onUpdate)
|
|
92
|
+
full += ` ON UPDATE ${fk.onUpdate}`;
|
|
93
|
+
return full;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Grammar } from "./Grammar.js";
|
|
2
|
+
import type { ColumnDefinition } from "../../types/index.js";
|
|
3
|
+
export declare class MySqlGrammar extends Grammar {
|
|
4
|
+
protected wrappers: {
|
|
5
|
+
prefix: string;
|
|
6
|
+
suffix: string;
|
|
7
|
+
};
|
|
8
|
+
protected getType(column: ColumnDefinition): string;
|
|
9
|
+
protected modifyUnsigned(column: ColumnDefinition): string;
|
|
10
|
+
protected modifyAutoIncrement(column: ColumnDefinition): string;
|
|
11
|
+
protected modifyComment(column: ColumnDefinition): string;
|
|
12
|
+
protected getColumn(_blueprint: any, column: ColumnDefinition): string;
|
|
13
|
+
compileColumnRename(table: string, from: string, to: string): string;
|
|
14
|
+
compileDropColumn(table: string, columns: string[]): string;
|
|
15
|
+
compileIndex(table: string, index: any): string;
|
|
16
|
+
compileCreate(blueprint: any, table: string): string;
|
|
17
|
+
compileCreateIfNotExists(blueprint: any, table: string): string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Grammar } from "./Grammar.js";
|
|
2
|
+
export class MySqlGrammar extends Grammar {
|
|
3
|
+
wrappers = { prefix: "`", suffix: "`" };
|
|
4
|
+
getType(column) {
|
|
5
|
+
switch (column.type) {
|
|
6
|
+
case "string":
|
|
7
|
+
return `VARCHAR(${column.length || 255})`;
|
|
8
|
+
case "text":
|
|
9
|
+
return "TEXT";
|
|
10
|
+
case "integer":
|
|
11
|
+
return "INT";
|
|
12
|
+
case "bigInteger":
|
|
13
|
+
return "BIGINT";
|
|
14
|
+
case "smallInteger":
|
|
15
|
+
return "SMALLINT";
|
|
16
|
+
case "tinyInteger":
|
|
17
|
+
return "TINYINT";
|
|
18
|
+
case "float":
|
|
19
|
+
return `FLOAT(${column.precision || 8}, ${column.scale || 2})`;
|
|
20
|
+
case "double":
|
|
21
|
+
return `DOUBLE(${column.precision || 8}, ${column.scale || 2})`;
|
|
22
|
+
case "decimal":
|
|
23
|
+
return `DECIMAL(${column.precision || 8}, ${column.scale || 2})`;
|
|
24
|
+
case "boolean":
|
|
25
|
+
return "BOOLEAN";
|
|
26
|
+
case "date":
|
|
27
|
+
return "DATE";
|
|
28
|
+
case "dateTime":
|
|
29
|
+
return "DATETIME";
|
|
30
|
+
case "time":
|
|
31
|
+
return "TIME";
|
|
32
|
+
case "timestamp":
|
|
33
|
+
return "TIMESTAMP";
|
|
34
|
+
case "json":
|
|
35
|
+
return "JSON";
|
|
36
|
+
case "jsonb":
|
|
37
|
+
return "JSON";
|
|
38
|
+
case "binary":
|
|
39
|
+
return "BLOB";
|
|
40
|
+
case "uuid":
|
|
41
|
+
return "CHAR(36)";
|
|
42
|
+
case "enum":
|
|
43
|
+
return `ENUM('${(column.values || []).join("','")}')`;
|
|
44
|
+
default:
|
|
45
|
+
return "TEXT";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
modifyUnsigned(column) {
|
|
49
|
+
return column.unsigned ? " UNSIGNED" : "";
|
|
50
|
+
}
|
|
51
|
+
modifyAutoIncrement(column) {
|
|
52
|
+
return column.autoIncrement ? " AUTO_INCREMENT" : "";
|
|
53
|
+
}
|
|
54
|
+
modifyComment(column) {
|
|
55
|
+
return column.comment ? ` COMMENT '${column.comment.replace(/'/g, "\\'")}'` : "";
|
|
56
|
+
}
|
|
57
|
+
getColumn(_blueprint, column) {
|
|
58
|
+
let sql = `${this.wrap(column.name)} ${this.getType(column)}`;
|
|
59
|
+
if (column.unsigned)
|
|
60
|
+
sql += this.modifyUnsigned(column);
|
|
61
|
+
if (!column.nullable)
|
|
62
|
+
sql += " NOT NULL";
|
|
63
|
+
if (column.default !== undefined)
|
|
64
|
+
sql += ` DEFAULT ${this.getDefaultValue(column.default)}`;
|
|
65
|
+
if (column.autoIncrement)
|
|
66
|
+
sql += this.modifyAutoIncrement(column);
|
|
67
|
+
if (column.unique)
|
|
68
|
+
sql += " UNIQUE";
|
|
69
|
+
if (column.primary)
|
|
70
|
+
sql += " PRIMARY KEY";
|
|
71
|
+
if (column.comment)
|
|
72
|
+
sql += this.modifyComment(column);
|
|
73
|
+
return sql;
|
|
74
|
+
}
|
|
75
|
+
compileColumnRename(table, from, to) {
|
|
76
|
+
// MySQL requires full column definition for rename; simplified here.
|
|
77
|
+
return `ALTER TABLE ${this.wrap(table)} RENAME COLUMN ${this.wrap(from)} TO ${this.wrap(to)}`;
|
|
78
|
+
}
|
|
79
|
+
compileDropColumn(table, columns) {
|
|
80
|
+
return `ALTER TABLE ${this.wrap(table)} ${columns.map((col) => `DROP COLUMN ${this.wrap(col)}`).join(", ")}`;
|
|
81
|
+
}
|
|
82
|
+
compileIndex(table, index) {
|
|
83
|
+
const type = index.unique ? "UNIQUE INDEX" : "INDEX";
|
|
84
|
+
return `ALTER TABLE ${this.wrap(table)} ADD ${type} ${this.wrap(index.name)} (${this.wrapArray(index.columns).join(", ")})`;
|
|
85
|
+
}
|
|
86
|
+
compileCreate(blueprint, table) {
|
|
87
|
+
const columns = this.getColumns(blueprint).map((col) => ` ${col}`).join(",\n");
|
|
88
|
+
const sql = `CREATE TABLE ${this.wrap(table)} (\n${columns}\n)`;
|
|
89
|
+
return sql;
|
|
90
|
+
}
|
|
91
|
+
compileCreateIfNotExists(blueprint, table) {
|
|
92
|
+
const columns = this.getColumns(blueprint).map((col) => ` ${col}`).join(",\n");
|
|
93
|
+
const sql = `CREATE TABLE IF NOT EXISTS ${this.wrap(table)} (\n${columns}\n)`;
|
|
94
|
+
return sql;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Grammar } from "./Grammar.js";
|
|
2
|
+
import type { ColumnDefinition } from "../../types/index.js";
|
|
3
|
+
export declare class PostgresGrammar extends Grammar {
|
|
4
|
+
protected wrappers: {
|
|
5
|
+
prefix: string;
|
|
6
|
+
suffix: string;
|
|
7
|
+
};
|
|
8
|
+
protected getType(column: ColumnDefinition): string;
|
|
9
|
+
protected modifyAutoIncrement(column: ColumnDefinition): string;
|
|
10
|
+
protected getColumn(_blueprint: any, column: ColumnDefinition): string;
|
|
11
|
+
compileColumnRename(table: string, from: string, to: string): string;
|
|
12
|
+
compileDropColumn(table: string, columns: string[]): string;
|
|
13
|
+
compileIndex(table: string, index: any): string;
|
|
14
|
+
compileCreate(blueprint: any, table: string): string;
|
|
15
|
+
compileCreateIfNotExists(blueprint: any, table: string): string;
|
|
16
|
+
}
|