drizzle-orm 0.9.16 → 0.9.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-orm",
3
- "version": "0.9.16",
3
+ "version": "0.9.17",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,5 +1,12 @@
1
+ import { DB } from '../db';
1
2
  import { AbstractTable } from '../tables';
2
3
  import Enum from '../types/type';
4
+ interface EnumsAsObject {
5
+ [name: string]: {
6
+ name: string;
7
+ values: string[];
8
+ };
9
+ }
3
10
  interface ColumnAsObject {
4
11
  [name: string]: {
5
12
  name?: string;
@@ -37,5 +44,10 @@ export default class MigrationSerializer {
37
44
  [key: string]: Enum<any>;
38
45
  };
39
46
  };
47
+ fromDatabase: (db: DB) => Promise<{
48
+ version: string;
49
+ tables: TableAsObject;
50
+ enums: EnumsAsObject;
51
+ }>;
40
52
  }
41
53
  export {};
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable max-classes-per-file */
2
3
  /* eslint-disable import/no-named-as-default-member */
3
4
  /* eslint-disable import/no-named-as-default */
4
5
  /* eslint-disable no-param-reassign */
@@ -69,6 +70,172 @@ class MigrationSerializer {
69
70
  }, {});
70
71
  return { version: '1', tables: result, enums: enumsToReturn };
71
72
  };
73
+ this.fromDatabase = async (db) => {
74
+ var _a;
75
+ const result = {};
76
+ const allTables = await db.session().execute('SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema != \'pg_catalog\' and table_schema != \'information_schema\';');
77
+ for await (const row of allTables.rows) {
78
+ try {
79
+ // const tableSchema = row.table_schema;
80
+ const tableName = row.table_name;
81
+ const columnToReturn = {};
82
+ const indexToReturn = {};
83
+ const tableResponse = await db.session().execute(`SELECT a.attrelid::regclass::text, a.attname
84
+ , CASE WHEN a.atttypid = ANY ('{int,int8,int2}'::regtype[])
85
+ AND EXISTS (
86
+ SELECT FROM pg_attrdef ad
87
+ WHERE ad.adrelid = a.attrelid
88
+ AND ad.adnum = a.attnum
89
+ AND pg_get_expr(ad.adbin, ad.adrelid)
90
+ = 'nextval('''
91
+ || (pg_get_serial_sequence (a.attrelid::regclass::text
92
+ , a.attname))::regclass
93
+ || '''::regclass)'
94
+ )
95
+ THEN CASE a.atttypid
96
+ WHEN 'int'::regtype THEN 'serial'
97
+ WHEN 'int8'::regtype THEN 'bigserial'
98
+ WHEN 'int2'::regtype THEN 'smallserial'
99
+ END
100
+ ELSE format_type(a.atttypid, a.atttypmod)
101
+ END AS data_type, INFORMATION_SCHEMA.COLUMNS.table_name, INFORMATION_SCHEMA.COLUMNS.column_name, INFORMATION_SCHEMA.COLUMNS.column_default
102
+ FROM pg_attribute a
103
+ JOIN INFORMATION_SCHEMA.COLUMNS ON INFORMATION_SCHEMA.COLUMNS.column_name = a.attname
104
+ WHERE a.attrelid = '${tableName}'::regclass and INFORMATION_SCHEMA.COLUMNS.table_name = '${tableName}'
105
+ AND a.attnum > 0
106
+ AND NOT a.attisdropped
107
+ ORDER BY a.attnum;`);
108
+ const tableConstraints = await db.session().execute(`SELECT c.column_name, c.data_type, constraint_type, constraint_name
109
+ FROM information_schema.table_constraints tc
110
+ JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)
111
+ JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema
112
+ AND tc.table_name = c.table_name AND ccu.column_name = c.column_name
113
+ WHERE tc.table_name = '${tableName}';`);
114
+ const tableForeignKeys = await db.session().execute(`SELECT
115
+ tc.table_schema,
116
+ tc.constraint_name,
117
+ tc.table_name,
118
+ kcu.column_name,
119
+ ccu.table_schema AS foreign_table_schema,
120
+ ccu.table_name AS foreign_table_name,
121
+ ccu.column_name AS foreign_column_name,
122
+ rc.delete_rule, rc.update_rule
123
+ FROM
124
+ information_schema.table_constraints AS tc
125
+ JOIN information_schema.key_column_usage AS kcu
126
+ ON tc.constraint_name = kcu.constraint_name
127
+ AND tc.table_schema = kcu.table_schema
128
+ JOIN information_schema.constraint_column_usage AS ccu
129
+ ON ccu.constraint_name = tc.constraint_name
130
+ AND ccu.table_schema = tc.table_schema
131
+ JOIN information_schema.referential_constraints AS rc
132
+ ON ccu.constraint_name = rc.constraint_name
133
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='${tableName}';`);
134
+ const mappedRefernces = {};
135
+ for (const fk of tableForeignKeys.rows) {
136
+ // const tableFrom = fk.table_name;
137
+ const columnFrom = fk.column_name;
138
+ const tableTo = fk.foreign_table_name;
139
+ const columnTo = fk.foreign_column_name;
140
+ const foreignKeyName = fk.constraint_name;
141
+ const onUpdate = fk.update_rule;
142
+ const onDelete = fk.delete_rule;
143
+ mappedRefernces[columnFrom] = {
144
+ foreignKeyName,
145
+ table: tableTo,
146
+ column: columnTo,
147
+ onDelete: onUpdate ? `ON UPDATE ${onUpdate}` : undefined,
148
+ onUpdate: onDelete ? `ON DELETE ${onDelete}` : undefined,
149
+ };
150
+ }
151
+ for (const columnResponse of tableResponse.rows) {
152
+ const columnName = columnResponse.attname;
153
+ const columnType = columnResponse.data_type;
154
+ const primaryKey = tableConstraints.rows.filter((mapRow) => columnName === mapRow.column_name && mapRow.constraint_type === 'PRIMARY KEY');
155
+ const uniqueKey = tableConstraints.rows.filter((mapRow) => columnName === mapRow.column_name && mapRow.constraint_type === 'UNIQUE');
156
+ const defaultValue = columnResponse.column_default === null
157
+ ? undefined : columnResponse.column_default;
158
+ const isSerial = columnType === 'serial';
159
+ columnToReturn[columnName] = {
160
+ name: columnName,
161
+ type: columnType,
162
+ primaryKey: !!primaryKey[0],
163
+ unique: !!uniqueKey[0],
164
+ default: isSerial ? undefined : defaultValue,
165
+ notNull: !columnResponse.is_nullable,
166
+ references: (_a = mappedRefernces[columnName]) !== null && _a !== void 0 ? _a : undefined,
167
+ };
168
+ }
169
+ const dbIndexes = await db.session().execute(`select
170
+ t.relname as table_name,
171
+ i.relname as index_name,
172
+ a.attname as column_name
173
+ from
174
+ pg_class t,
175
+ pg_class i,
176
+ pg_index ix,
177
+ pg_attribute a
178
+ where
179
+ t.oid = ix.indrelid
180
+ and i.oid = ix.indexrelid
181
+ and a.attrelid = t.oid
182
+ and a.attnum = ANY(ix.indkey)
183
+ and t.relkind = 'r'
184
+ and t.relname = '${tableName}'
185
+ order by
186
+ t.relname,
187
+ i.relname;`);
188
+ for (const dbIndex of dbIndexes.rows) {
189
+ const indexName = dbIndex.index_name;
190
+ const indexColumnName = dbIndex.column_name;
191
+ if (indexToReturn[indexName] !== undefined && indexToReturn[indexName] !== null) {
192
+ indexToReturn[indexName].columns[indexColumnName] = {
193
+ name: indexColumnName,
194
+ };
195
+ }
196
+ else {
197
+ indexToReturn[indexName] = {
198
+ name: indexName,
199
+ columns: {
200
+ [indexColumnName]: {
201
+ name: indexColumnName,
202
+ },
203
+ },
204
+ };
205
+ }
206
+ }
207
+ result[tableName] = {
208
+ name: tableName,
209
+ columns: columnToReturn,
210
+ indexes: indexToReturn,
211
+ };
212
+ }
213
+ catch (e) {
214
+ console.log(e);
215
+ }
216
+ }
217
+ const allEnums = await db.session().execute(`select n.nspname as enum_schema,
218
+ t.typname as enum_name,
219
+ e.enumlabel as enum_value
220
+ from pg_type t
221
+ join pg_enum e on t.oid = e.enumtypid
222
+ join pg_catalog.pg_namespace n ON n.oid = t.typnamespace;`);
223
+ const enumsToReturn = {};
224
+ for (const dbEnum of allEnums.rows) {
225
+ const enumName = dbEnum.enum_name;
226
+ const enumValue = dbEnum.enum_value;
227
+ if (enumsToReturn[enumName] !== undefined && enumsToReturn[enumName] !== null) {
228
+ enumsToReturn[enumName].values.push(enumValue);
229
+ }
230
+ else {
231
+ enumsToReturn[enumName] = {
232
+ name: enumName,
233
+ values: [enumValue],
234
+ };
235
+ }
236
+ }
237
+ return { version: '1', tables: result, enums: enumsToReturn };
238
+ };
72
239
  }
73
240
  }
74
241
  exports.default = MigrationSerializer;