@or-sdk/pgsql 0.22.5-pgsql.0 → 0.23.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/Pgsql.js +250 -8
  3. package/dist/cjs/Pgsql.js.map +1 -1
  4. package/dist/cjs/constants.js +2 -1
  5. package/dist/cjs/constants.js.map +1 -1
  6. package/dist/cjs/utils/createSchemaQuery.js +4 -0
  7. package/dist/cjs/utils/createSchemaQuery.js.map +1 -0
  8. package/dist/cjs/utils/encodeValue.js +17 -0
  9. package/dist/cjs/utils/encodeValue.js.map +1 -0
  10. package/dist/cjs/utils/getAddColumnsQuery.js +6 -0
  11. package/dist/cjs/utils/getAddColumnsQuery.js.map +1 -0
  12. package/dist/cjs/utils/getCreateTableQuery.js +6 -0
  13. package/dist/cjs/utils/getCreateTableQuery.js.map +1 -0
  14. package/dist/cjs/utils/getDeleteRowsQuery.js +9 -0
  15. package/dist/cjs/utils/getDeleteRowsQuery.js.map +1 -0
  16. package/dist/cjs/utils/getDropSchemaQuery.js +4 -0
  17. package/dist/cjs/utils/getDropSchemaQuery.js.map +1 -0
  18. package/dist/cjs/utils/getDropTableQuery.js +4 -0
  19. package/dist/cjs/utils/getDropTableQuery.js.map +1 -0
  20. package/dist/cjs/utils/getEditRowQuery.js +10 -0
  21. package/dist/cjs/utils/getEditRowQuery.js.map +1 -0
  22. package/dist/cjs/utils/getGenerateTableSchemaQuery.js +4 -0
  23. package/dist/cjs/utils/getGenerateTableSchemaQuery.js.map +1 -0
  24. package/dist/cjs/utils/getGetPrimaryKeysQuery.js +4 -0
  25. package/dist/cjs/utils/getGetPrimaryKeysQuery.js.map +1 -0
  26. package/dist/cjs/utils/getInsertKeys.js +9 -0
  27. package/dist/cjs/utils/getInsertKeys.js.map +1 -0
  28. package/dist/cjs/utils/getInsertQueries.js +18 -0
  29. package/dist/cjs/utils/getInsertQueries.js.map +1 -0
  30. package/dist/cjs/utils/getListTablesQuery.js +4 -0
  31. package/dist/cjs/utils/getListTablesQuery.js.map +1 -0
  32. package/dist/cjs/utils/getSelectAllCountQuery.js +4 -0
  33. package/dist/cjs/utils/getSelectAllCountQuery.js.map +1 -0
  34. package/dist/cjs/utils/getSelectAllQuery.js +4 -0
  35. package/dist/cjs/utils/getSelectAllQuery.js.map +1 -0
  36. package/dist/cjs/utils/index.js +33 -1
  37. package/dist/cjs/utils/index.js.map +1 -1
  38. package/dist/cjs/utils/splitPrimaryKeys.js +8 -0
  39. package/dist/cjs/utils/splitPrimaryKeys.js.map +1 -0
  40. package/dist/esm/Pgsql.js +160 -8
  41. package/dist/esm/Pgsql.js.map +1 -1
  42. package/dist/esm/constants.js +2 -0
  43. package/dist/esm/constants.js.map +1 -1
  44. package/dist/esm/utils/createSchemaQuery.js +2 -0
  45. package/dist/esm/utils/createSchemaQuery.js.map +1 -0
  46. package/dist/esm/utils/encodeValue.js +12 -0
  47. package/dist/esm/utils/encodeValue.js.map +1 -0
  48. package/dist/esm/utils/getAddColumnsQuery.js +2 -0
  49. package/dist/esm/utils/getAddColumnsQuery.js.map +1 -0
  50. package/dist/esm/utils/getCreateTableQuery.js +2 -0
  51. package/dist/esm/utils/getCreateTableQuery.js.map +1 -0
  52. package/dist/esm/utils/getDeleteRowsQuery.js +8 -0
  53. package/dist/esm/utils/getDeleteRowsQuery.js.map +1 -0
  54. package/dist/esm/utils/getDropSchemaQuery.js +2 -0
  55. package/dist/esm/utils/getDropSchemaQuery.js.map +1 -0
  56. package/dist/esm/utils/getDropTableQuery.js +2 -0
  57. package/dist/esm/utils/getDropTableQuery.js.map +1 -0
  58. package/dist/esm/utils/getEditRowQuery.js +10 -0
  59. package/dist/esm/utils/getEditRowQuery.js.map +1 -0
  60. package/dist/esm/utils/getGenerateTableSchemaQuery.js +18 -0
  61. package/dist/esm/utils/getGenerateTableSchemaQuery.js.map +1 -0
  62. package/dist/esm/utils/getGetPrimaryKeysQuery.js +9 -0
  63. package/dist/esm/utils/getGetPrimaryKeysQuery.js.map +1 -0
  64. package/dist/esm/utils/getInsertKeys.js +7 -0
  65. package/dist/esm/utils/getInsertKeys.js.map +1 -0
  66. package/dist/esm/utils/getInsertQueries.js +14 -0
  67. package/dist/esm/utils/getInsertQueries.js.map +1 -0
  68. package/dist/esm/utils/getListTablesQuery.js +4 -0
  69. package/dist/esm/utils/getListTablesQuery.js.map +1 -0
  70. package/dist/esm/utils/getSelectAllCountQuery.js +2 -0
  71. package/dist/esm/utils/getSelectAllCountQuery.js.map +1 -0
  72. package/dist/esm/utils/getSelectAllQuery.js +2 -0
  73. package/dist/esm/utils/getSelectAllQuery.js.map +1 -0
  74. package/dist/esm/utils/index.js +16 -0
  75. package/dist/esm/utils/index.js.map +1 -1
  76. package/dist/esm/utils/splitPrimaryKeys.js +3 -0
  77. package/dist/esm/utils/splitPrimaryKeys.js.map +1 -0
  78. package/dist/types/Pgsql.d.ts +45 -4
  79. package/dist/types/constants.d.ts +1 -0
  80. package/dist/types/types.d.ts +66 -7
  81. package/dist/types/utils/createSchemaQuery.d.ts +2 -0
  82. package/dist/types/utils/encodeValue.d.ts +3 -0
  83. package/dist/types/utils/getAddColumnsQuery.d.ts +3 -0
  84. package/dist/types/utils/getCreateTableQuery.d.ts +3 -0
  85. package/dist/types/utils/getDeleteRowsQuery.d.ts +3 -0
  86. package/dist/types/utils/getDropSchemaQuery.d.ts +2 -0
  87. package/dist/types/utils/getDropTableQuery.d.ts +2 -0
  88. package/dist/types/utils/getEditRowQuery.d.ts +3 -0
  89. package/dist/types/utils/getGenerateTableSchemaQuery.d.ts +2 -0
  90. package/dist/types/utils/getGetPrimaryKeysQuery.d.ts +2 -0
  91. package/dist/types/utils/getInsertKeys.d.ts +3 -0
  92. package/dist/types/utils/getInsertQueries.d.ts +3 -0
  93. package/dist/types/utils/getListTablesQuery.d.ts +2 -0
  94. package/dist/types/utils/getSelectAllCountQuery.d.ts +2 -0
  95. package/dist/types/utils/getSelectAllQuery.d.ts +2 -0
  96. package/dist/types/utils/index.d.ts +16 -0
  97. package/dist/types/utils/splitPrimaryKeys.d.ts +2 -0
  98. package/package.json +5 -3
  99. package/src/Pgsql.ts +310 -20
  100. package/src/constants.ts +3 -0
  101. package/src/types.ts +76 -8
  102. package/src/utils/createSchemaQuery.ts +1 -0
  103. package/src/utils/encodeValue.ts +11 -0
  104. package/src/utils/getAddColumnsQuery.ts +4 -0
  105. package/src/utils/getCreateTableQuery.ts +4 -0
  106. package/src/utils/getDeleteRowsQuery.ts +10 -0
  107. package/src/utils/getDropSchemaQuery.ts +1 -0
  108. package/src/utils/getDropTableQuery.ts +1 -0
  109. package/src/utils/getEditRowQuery.ts +12 -0
  110. package/src/utils/getGenerateTableSchemaQuery.ts +17 -0
  111. package/src/utils/getGetPrimaryKeysQuery.ts +8 -0
  112. package/src/utils/getInsertKeys.ts +9 -0
  113. package/src/utils/getInsertQueries.ts +18 -0
  114. package/src/utils/getListTablesQuery.ts +3 -0
  115. package/src/utils/getSelectAllCountQuery.ts +1 -0
  116. package/src/utils/getSelectAllQuery.ts +1 -0
  117. package/src/utils/index.ts +16 -0
  118. package/src/utils/splitPrimaryKeys.ts +3 -0
@@ -0,0 +1,2 @@
1
+ declare const _default: (schema: string) => string;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: (schema: string, table: string) => string;
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { Row } from '../types';
2
+ declare function getEditRowQuery(schema: string, table: string, key: string, value: unknown, row: Row, primaryKeys: string): string;
3
+ export default getEditRowQuery;
@@ -0,0 +1,2 @@
1
+ declare const _default: (schema: string, table: string) => string;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: (schema: string, table: string) => string;
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { Row } from '../types';
2
+ declare function getInsertKeys(rows: Row[]): string[];
3
+ export default getInsertKeys;
@@ -0,0 +1,3 @@
1
+ import { Row } from '../types';
2
+ declare function getInsertQueries(schema: string, table: string, insertRows: Row[], chunkSize: number): string[];
3
+ export default getInsertQueries;
@@ -0,0 +1,2 @@
1
+ declare const _default: (schema: string) => string;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: (query: string) => string;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: (query: string, offset: number, chunkSize: number) => string;
2
+ export default _default;
@@ -1 +1,17 @@
1
1
  export { default as extractDatabaseNames } from './extractDatabaseNames';
2
+ export { default as getInsertKeys } from './getInsertKeys';
3
+ export { default as encodeValue } from './encodeValue';
4
+ export { default as splitPrimaryKeys } from './splitPrimaryKeys';
5
+ export { default as getListTablesQuery } from './getListTablesQuery';
6
+ export { default as createSchemaQuery } from './createSchemaQuery';
7
+ export { default as getDropSchemaQuery } from './getDropSchemaQuery';
8
+ export { default as getCreateTableQuery } from './getCreateTableQuery';
9
+ export { default as getDropTableQuery } from './getDropTableQuery';
10
+ export { default as getAddColumnsQuery } from './getAddColumnsQuery';
11
+ export { default as getInsertQueries } from './getInsertQueries';
12
+ export { default as getSelectAllCountQuery } from './getSelectAllCountQuery';
13
+ export { default as getSelectAllQuery } from './getSelectAllQuery';
14
+ export { default as getEditRowQuery } from './getEditRowQuery';
15
+ export { default as getDeleteRowsQuery } from './getDeleteRowsQuery';
16
+ export { default as getGenerateTableSchemaQuery } from './getGenerateTableSchemaQuery';
17
+ export { default as getGetPrimaryKeysQuery } from './getGetPrimaryKeysQuery';
@@ -0,0 +1,2 @@
1
+ declare const _default: (primaryKeys: string) => string[];
2
+ export default _default;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.22.5-pgsql.0",
2
+ "version": "0.23.0",
3
3
  "name": "@or-sdk/pgsql",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
@@ -16,6 +16,7 @@
16
16
  "clean": "rm -rf ./dist"
17
17
  },
18
18
  "devDependencies": {
19
+ "@types/lodash": "^4.14.176",
19
20
  "concurrently": "^6.4.0",
20
21
  "typescript": "^4.4.4"
21
22
  },
@@ -23,7 +24,8 @@
23
24
  "access": "public"
24
25
  },
25
26
  "dependencies": {
26
- "@or-sdk/base": "^0.23.0-pgsql.0"
27
+ "@or-sdk/base": "^0.22.4",
28
+ "lodash": "^4.17.21"
27
29
  },
28
- "gitHead": "1ae7d9d2916f04d84b9cd47b525cb56d1ce1274c"
30
+ "gitHead": "06d3e4784a68183e3b39e3aac6d6782eb5cbd3c0"
29
31
  }
package/src/Pgsql.ts CHANGED
@@ -1,12 +1,20 @@
1
1
  import { Base, ServiceDiscoveryResponse, List, makeList } from '@or-sdk/base';
2
2
  import {
3
- CreateDatabaseResponse, DropDatabaseResponse,
4
- ExecuteQueryArgs, ExecuteQueryResponse,
3
+ AddColumnsArgs,
4
+ CreateDatabaseResponse, CreateTableArgs, DeleteRowsArgs, DropDatabaseResponse, EditRowArgs,
5
+ ExecuteQueryArgs, ExecuteQueryResponse, GetDBSizeResult, InsertArgs,
5
6
  ListDatabasesResponse,
6
- PgsqlConfig
7
+ PgsqlConfig, Row, SelectAllArgs,
7
8
  } from './types';
8
- import { SERVICE_KEY } from './constants';
9
- import { extractDatabaseNames } from './utils';
9
+ import { LIST_SCHEMAS_QUERY, SERVICE_KEY } from './constants';
10
+ import {
11
+ extractDatabaseNames, getAddColumnsQuery,
12
+ getCreateTableQuery,
13
+ getDropSchemaQuery,
14
+ getDropTableQuery, getEditRowQuery, getGenerateTableSchemaQuery, getInsertQueries,
15
+ getListTablesQuery, getSelectAllCountQuery, getSelectAllQuery,
16
+ getDeleteRowsQuery, createSchemaQuery, getGetPrimaryKeysQuery,
17
+ } from './utils';
10
18
 
11
19
  /**
12
20
  * OneReach Pgsql service client
@@ -43,12 +51,19 @@ export class Pgsql extends Base {
43
51
  /**
44
52
  * Execute query
45
53
  * ```typescript
46
- * const result = await pgsql.executeQuery();
54
+ * const result = await pgsql.executeQuery({
55
+ * query: 'select * from table',
56
+ * database: 'db-name'
57
+ * });
47
58
  * ```
48
59
  */
49
- public async executeQuery({ query, params, database }: ExecuteQueryArgs): Promise<ExecuteQueryResponse> {
50
- return this.callApi<ExecuteQueryResponse>({
51
- data: { query, params, database },
60
+ public async executeQuery<T>({ query, params, database }: ExecuteQueryArgs): Promise<ExecuteQueryResponse<T>> {
61
+ return this.callApi<ExecuteQueryResponse<T>>({
62
+ data: {
63
+ query,
64
+ params,
65
+ database,
66
+ },
52
67
  method: 'POST',
53
68
  route: 'query',
54
69
  });
@@ -63,7 +78,7 @@ export class Pgsql extends Base {
63
78
  public async listDatabases(): Promise<List<string>> {
64
79
  const { databases } = await this.callApi<ListDatabasesResponse>({
65
80
  method: 'GET',
66
- route: 'databases'
81
+ route: 'databases',
67
82
  });
68
83
 
69
84
  return makeList<string>(extractDatabaseNames(databases));
@@ -72,15 +87,15 @@ export class Pgsql extends Base {
72
87
  /**
73
88
  * Create database
74
89
  * ```typescript
75
- * const result = await pgsql.createDatabase();
90
+ * const result = await pgsql.createDatabase({ database: 'db-name' });
76
91
  * ```
77
92
  */
78
- public async createDatabase(database: string): Promise<CreateDatabaseResponse> {
93
+ public async createDatabase({ database }: { database: string; }): Promise<CreateDatabaseResponse> {
79
94
  return this.callApi<CreateDatabaseResponse>({
80
95
  data: { database },
81
96
  method: 'PUT',
82
- route: 'databases'
83
- })
97
+ route: 'databases',
98
+ });
84
99
  }
85
100
 
86
101
  /**
@@ -88,11 +103,11 @@ export class Pgsql extends Base {
88
103
  *
89
104
  * @deprecated route not available
90
105
  * ```typescript
91
- * const result = await pgsql.getDatabaseInfo();
106
+ * const result = await pgsql.getDatabaseInfo({ database: 'db-name' });
92
107
  * ```
93
108
  */
94
109
  // TODO: uncomment or replace route?
95
- // public async getDatabaseInfo(database: string): Promise<unknown> {
110
+ // public async getDatabaseInfo({ database }: { database: string; }): Promise<unknown> {
96
111
  // return this.callApi<unknown>({
97
112
  // method: 'GET',
98
113
  // route: `databases/${encodeURIComponent(database)}`
@@ -102,14 +117,289 @@ export class Pgsql extends Base {
102
117
  /**
103
118
  * Drop database
104
119
  * ```typescript
105
- * const result = await pgsql.dropDatabase();
120
+ * const result = await pgsql.dropDatabase({ database: 'db-name' });
106
121
  * ```
107
122
  */
108
- public async dropDatabase(database: string): Promise<DropDatabaseResponse> {
123
+ public async dropDatabase({ database }: { database: string; }): Promise<DropDatabaseResponse> {
109
124
  return this.callApi<DropDatabaseResponse>({
110
125
  data: { database },
111
126
  method: 'DELETE',
112
- route: 'databases'
113
- })
127
+ route: 'databases',
128
+ });
129
+ }
130
+
131
+ /**
132
+ * List tables
133
+ * ```typescript
134
+ * const result = await pgsql.listTables({ database: 'db-name', schema: 'schema-name' });
135
+ * ```
136
+ */
137
+ public async listTables({ database, schema = 'public' }: { database: string; schema?: string; }): Promise<List<string>> {
138
+ const { rows } = await this.executeQuery<{ table_name: string; }>({
139
+ query: getListTablesQuery(schema),
140
+ database,
141
+ });
142
+ return makeList<string>(rows.map(x => x.table_name));
143
+ }
144
+
145
+ /**
146
+ * List schemas
147
+ * ```typescript
148
+ * const result = await pgsql.listSchemas({ database: 'db-name' });
149
+ * ```
150
+ */
151
+ public async listSchemas({ database }: { database: string; }): Promise<List<string>> {
152
+ const { rows } = await this.executeQuery<{ schema_name: string; }>({
153
+ query: LIST_SCHEMAS_QUERY,
154
+ database,
155
+ });
156
+ return makeList<string>(rows.map(x => x.schema_name));
157
+ }
158
+
159
+ /**
160
+ * Create schema
161
+ * ```typescript
162
+ * const result = await pgsql.createSchema({ database: 'db-name', schema: 'schema-name' });
163
+ * ```
164
+ */
165
+ public async createSchema({ database, schema }: { database: string; schema: string; }): Promise<ExecuteQueryResponse<void>> {
166
+ return this.executeQuery<void>({
167
+ query: createSchemaQuery(schema),
168
+ database,
169
+ });
170
+ }
171
+
172
+ /**
173
+ * Drop schema
174
+ * ```typescript
175
+ * const result = await pgsql.dropSchema({ database: 'db-name', schema: 'schema-name' });
176
+ * ```
177
+ */
178
+ public async dropSchema({ database, schema }: { database: string; schema: string; }): Promise<ExecuteQueryResponse<void>> {
179
+ return this.executeQuery<void>({
180
+ query: getDropSchemaQuery(schema),
181
+ database,
182
+ });
183
+ }
184
+
185
+ /**
186
+ * Drop table
187
+ * ```typescript
188
+ * const result = await pgsql.dropSchema({ database: 'db-name', schema: 'schema-name', table: 'table-name' });
189
+ * ```
190
+ */
191
+ public async dropTable({ database, schema, table }: { database: string; schema: string; table: string; }): Promise<ExecuteQueryResponse<void>> {
192
+ return this.executeQuery<void>({
193
+ query: getDropTableQuery(schema, table),
194
+ database,
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Create table
200
+ * ```typescript
201
+ * const result = await pgsql.createTable({
202
+ * database: 'db-name',
203
+ * schema: 'schema-name',
204
+ * table: 'table-name',
205
+ * columns: [
206
+ * { name: 'col1', type: 'integer' },
207
+ * { name: 'col2', type: 'text' }
208
+ * ],
209
+ * primaryKey: 'col1,col2'
210
+ * });
211
+ * ```
212
+ */
213
+ public async createTable({ database, schema, table, columns, primaryKey }: CreateTableArgs): Promise<ExecuteQueryResponse<void>> {
214
+ return this.executeQuery<void>({
215
+ query: getCreateTableQuery(schema, table, columns, primaryKey),
216
+ database,
217
+ });
218
+ }
219
+
220
+ /**
221
+ * Drop database
222
+ * ```typescript
223
+ * const result = await pgsql.addColumns({
224
+ * database: 'db-name',
225
+ * schema: 'schema-name',
226
+ * table: 'table-name',
227
+ * columns: [
228
+ * { name: 'col1', type: 'integer' },
229
+ * { name: 'col2', type: 'text' }
230
+ * ],
231
+ * });
232
+ * ```
233
+ */
234
+ public async addColumns({ database, schema, table, columns }: AddColumnsArgs): Promise<ExecuteQueryResponse<void>> {
235
+ return this.executeQuery<void>({
236
+ query: getAddColumnsQuery(schema, table, columns),
237
+ database,
238
+ });
239
+ }
240
+
241
+ /**
242
+ * Insert
243
+ * ```typescript
244
+ * const result = await pgsql.insert({
245
+ * database: 'db-name',
246
+ * schema: 'schema-name',
247
+ * table: 'table-name',
248
+ * rows: [
249
+ * { col1: 'value' }
250
+ * ],
251
+ * chunkSize: 300,
252
+ * context: { progress: 0 } // progress of insert will be set from 0 to 100
253
+ * });
254
+ * ```
255
+ */
256
+ public async insert({ database, schema, table, rows, chunkSize = 300, context }: InsertArgs): Promise<ExecuteQueryResponse<void>[]> {
257
+ const res = [];
258
+
259
+ const queries = getInsertQueries(schema, table, rows, chunkSize);
260
+
261
+ for (const [index, query] of Array.from(queries.entries())) {
262
+ res.push(await this.executeQuery<void>({
263
+ query,
264
+ database,
265
+ }));
266
+
267
+ if (context) {
268
+ context.progress = Math.min((index + 1) / (rows.length / Math.min(chunkSize, rows.length)), 1) * 100;
269
+ }
270
+ }
271
+
272
+ return res;
273
+ }
274
+
275
+ /**
276
+ * Select all
277
+ * ```typescript
278
+ * const result = await pgsql.selectAll({
279
+ * database: 'db-name',
280
+ * query: 'select * from table', // must be select only, without limit and offset
281
+ * chunkSize: 300,
282
+ * offset: 0,
283
+ * limit: 0,
284
+ * context: { progress: 0, total: 0 } // progress of select will be set from 0 to 100
285
+ * });
286
+ * ```
287
+ */
288
+ public async selectAll({ database, query, context, chunkSize = 1000, offset = 0, limit }: SelectAllArgs): Promise<List<Row>> {
289
+ let count: number, rows, result: Row[] = [];
290
+ if (limit && limit < chunkSize) {
291
+ chunkSize = limit;
292
+ }
293
+
294
+ if (context) {
295
+ const { rows } = await this.executeQuery<{ count: number; }>({
296
+ query: getSelectAllCountQuery(query),
297
+ database,
298
+ });
299
+ count = rows[0].count;
300
+ context.total = count;
301
+ }
302
+
303
+ do {
304
+ ({ rows } = await this.executeQuery<Row>({
305
+ query: getSelectAllQuery(query, offset, chunkSize),
306
+ database,
307
+ }));
308
+ offset += chunkSize;
309
+ result = result.concat(rows);
310
+ if (context) {
311
+ context.progress = Math.min(offset / count! * 100, 100);
312
+ }
313
+ if (limit && result.length >= limit) {
314
+ result = result.slice(0, limit);
315
+ break;
316
+ }
317
+ } while (rows.length);
318
+
319
+ return makeList<Row>(result);
320
+ }
321
+
322
+ /**
323
+ * Get primary keys
324
+ * ```typescript
325
+ * const result = await pgsql.getPrimaryKeys({ database: 'db-name', schema: 'schema-name', table: 'table-name' });
326
+ * ```
327
+ */
328
+ public async getPrimaryKeys({ database, schema, table }: { database: string; schema: string; table: string; }): Promise<string> {
329
+ const { rows } = await this.executeQuery<{ pk: string; }>({
330
+ database,
331
+ query: getGetPrimaryKeysQuery(schema, table),
332
+ });
333
+ return rows[0].pk;
334
+ }
335
+
336
+ /**
337
+ * Edit row
338
+ * ```typescript
339
+ * const result = await pgsql.editRow({
340
+ * database: 'db-name',
341
+ * schema: 'schema-name',
342
+ * table: 'table-name',
343
+ * key: 'col1',
344
+ * value: 'new_value',
345
+ * row: { pk: 'pk_val', col1: 'old_value' },
346
+ * primaryKeys: 'pk',
347
+ * });
348
+ * ```
349
+ */
350
+ public async editRow({ database, schema, table, key, value, row, primaryKeys }: EditRowArgs): Promise<ExecuteQueryResponse<void>> {
351
+ return this.executeQuery({
352
+ database,
353
+ query: getEditRowQuery(schema, table, key, value, row, primaryKeys),
354
+ });
355
+ }
356
+
357
+ /**
358
+ * Delete rows
359
+ * ```typescript
360
+ * const result = await pgsql.deleteRows({
361
+ * database: 'db-name',
362
+ * schema: 'schema-name',
363
+ * table: 'table-name',
364
+ * rows: [
365
+ * { pk: 'pk_val', col1: 'value' }
366
+ * ],
367
+ * primaryKeys: 'pk',
368
+ * });
369
+ * ```
370
+ */
371
+ public async deleteRows({ database, schema, table, rows, primaryKeys }: DeleteRowsArgs): Promise<ExecuteQueryResponse<void>> {
372
+ return this.executeQuery({
373
+ database,
374
+ query: getDeleteRowsQuery(schema, table, rows, primaryKeys),
375
+ });
376
+ }
377
+
378
+ /**
379
+ * Generate create table query for existing table
380
+ * ```typescript
381
+ * const result = await pgsql.generateTableSchema({ database: 'db-name', schema: 'schema-name', table: 'table-name' });
382
+ * ```
383
+ */
384
+ public async generateTableSchema({ database, schema, table }: { database: string; schema: string; table: string; }): Promise<string> {
385
+ const { rows } = await this.executeQuery<{ code: string; }>({
386
+ database,
387
+ query: getGenerateTableSchemaQuery(schema, table),
388
+ });
389
+
390
+ return rows[0].code;
391
+ }
392
+
393
+ /**
394
+ * Get database size
395
+ * ```typescript
396
+ * const result = await pgsql.getDBSize();
397
+ * ```
398
+ */
399
+ public async getDBSize(): Promise<GetDBSizeResult> {
400
+ return await this.callApi<GetDBSizeResult>({
401
+ method: 'GET',
402
+ route: 'size',
403
+ });
114
404
  }
115
405
  }
package/src/constants.ts CHANGED
@@ -1 +1,4 @@
1
1
  export const SERVICE_KEY = 'pgsql';
2
+
3
+ export const LIST_SCHEMAS_QUERY = `SELECT schema_name FROM information_schema.schemata
4
+ where schema_name not in ('pg_catalog', 'information_schema')`;
package/src/types.ts CHANGED
@@ -22,10 +22,6 @@ export type PgsqlConfig = {
22
22
  pgsqlUrl?: string;
23
23
  };
24
24
 
25
- export type QueryRow = {
26
- [key: string]: unknown;
27
- };
28
-
29
25
  export type QueryField = {
30
26
  name: string;
31
27
  tableID: number;
@@ -36,11 +32,11 @@ export type QueryField = {
36
32
  format: string;
37
33
  };
38
34
 
39
- export type ExecuteQueryResponse = {
35
+ export type ExecuteQueryResponse<T> = {
40
36
  command: string;
41
- rowCount: number;
37
+ rowCount: null | number;
42
38
  oid: null | number;
43
- rows: QueryRow[];
39
+ rows: T[];
44
40
  fields: QueryField[];
45
41
  RowCtor: null | unknown;
46
42
  rowAsArray: boolean;
@@ -48,7 +44,7 @@ export type ExecuteQueryResponse = {
48
44
 
49
45
  export type ExecuteQueryArgs = {
50
46
  query: string;
51
- params: {
47
+ params?: {
52
48
  [key: string]: unknown;
53
49
  };
54
50
  database: string;
@@ -73,3 +69,75 @@ export type ListDatabasesResponse = {
73
69
  export type DropDatabaseResponse = {
74
70
  ok?: number;
75
71
  };
72
+
73
+ export type GetDBSizeResult = {
74
+ usedSize: number;
75
+ sizeLimit: string | number;
76
+ };
77
+
78
+ export type TableColumn = {
79
+ name: string;
80
+ type: number;
81
+ };
82
+
83
+ export type CreateTableArgs = {
84
+ database: string;
85
+ schema: string;
86
+ table: string;
87
+ columns: TableColumn[];
88
+ primaryKey: string;
89
+ };
90
+
91
+ export type AddColumnsArgs = {
92
+ database: string;
93
+ schema: string;
94
+ table: string;
95
+ columns: TableColumn[];
96
+ };
97
+
98
+ export type Row = {
99
+ [key: string]: unknown;
100
+ };
101
+
102
+ export type InsertArgs = {
103
+ database: string;
104
+ schema: string;
105
+ table: string;
106
+ rows: Row[];
107
+ chunkSize: number;
108
+ context?: {
109
+ progress?: number;
110
+ };
111
+ };
112
+
113
+ export type EncodedValue = string | number | boolean;
114
+
115
+ export type SelectAllArgs = {
116
+ database: string;
117
+ query: string;
118
+ context?: {
119
+ progress?: number;
120
+ total?: number;
121
+ };
122
+ chunkSize?: number;
123
+ offset?: number;
124
+ limit?: number;
125
+ };
126
+
127
+ export type EditRowArgs = {
128
+ database: string;
129
+ schema: string;
130
+ table: string;
131
+ key: string;
132
+ value: unknown;
133
+ row: Row;
134
+ primaryKeys: string;
135
+ };
136
+
137
+ export type DeleteRowsArgs = {
138
+ database: string;
139
+ schema: string;
140
+ table: string;
141
+ rows: Row[];
142
+ primaryKeys: string;
143
+ };
@@ -0,0 +1 @@
1
+ export default (schema: string) => `create schema ${schema};`;
@@ -0,0 +1,11 @@
1
+ import { EncodedValue } from '../types';
2
+ import _ from 'lodash';
3
+
4
+ function encodeValue(value: unknown): EncodedValue {
5
+ if (_.isUndefined(value) || value === '' || _.isNull(value)) return 'NULL';
6
+ if (_.isString(value)) return `'${value.replaceAll('\'', '\'\'')}'`;
7
+ if (_.isNumber(value) || _.isBoolean(value)) return value;
8
+ return `'${JSON.stringify(value).replaceAll('\'', '\'\'')}'`;
9
+ }
10
+
11
+ export default encodeValue;
@@ -0,0 +1,4 @@
1
+ import { TableColumn } from '../types';
2
+
3
+ export default (schema: string, table: string, columns: TableColumn[]) =>
4
+ `alter table ${schema}.${table} ${columns.map(x => `add column ${x.name} ${x.type}`).join(', ')};`;
@@ -0,0 +1,4 @@
1
+ import { TableColumn } from '../types';
2
+
3
+ export default (schema: string, table: string, columns: TableColumn[], primaryKey: string) =>
4
+ `create table ${schema}.${table} (${columns.map(x => `${x.name} ${x.type}`).join(', ')}, primary key (${primaryKey}));`;
@@ -0,0 +1,10 @@
1
+ import { Row } from '../types';
2
+ import { encodeValue, splitPrimaryKeys } from '../utils';
3
+
4
+ function getDeleteRowQuery(schema: string, table: string, rows: Row[], primaryKeys: string): string {
5
+ const pk = splitPrimaryKeys(primaryKeys);
6
+ return `delete from ${schema}.${table}
7
+ where (${rows.map(row => `${pk.map(primaryKey => `${primaryKey} = ${encodeValue(row[primaryKey])}`).join(' AND ')}`).join(') \nOR (')})`;
8
+ }
9
+
10
+ export default getDeleteRowQuery;
@@ -0,0 +1 @@
1
+ export default (schema: string) => `drop schema ${schema} cascade;`;
@@ -0,0 +1 @@
1
+ export default (schema: string, table: string) => `drop table ${schema}.${table};`;
@@ -0,0 +1,12 @@
1
+ import { encodeValue, splitPrimaryKeys } from '../utils';
2
+ import { Row } from '../types';
3
+
4
+ function getEditRowQuery(schema: string, table: string, key: string, value: unknown, row: Row, primaryKeys: string): string {
5
+ value = encodeValue(value);
6
+ const pk = splitPrimaryKeys(primaryKeys);
7
+ return `update ${schema}.${table}
8
+ set ${key} = ${value}
9
+ where ${pk.map(primaryKey => `${primaryKey} = ${encodeValue(row[primaryKey])}`).join(' AND ')}`;
10
+ }
11
+
12
+ export default getEditRowQuery;
@@ -0,0 +1,17 @@
1
+ export default (schema: string, table: string) => `SELECT 'CREATE TABLE ' || '${schema}.${table}' || ' (' || '\n' || '' ||
2
+ string_agg(column_list.column_expr, ', ' || '\n' || '') ||
3
+ '' || ',\n' || 'PRIMARY KEY (' || (SELECT string_agg(a.attname, ', ') AS pk
4
+ FROM
5
+ pg_constraint AS c
6
+ CROSS JOIN LATERAL UNNEST(c.conkey) AS cols(colnum) -- conkey is a list of the columns of the constraint; so we split it into rows so that we can join all column numbers onto their names in pg_attribute
7
+ INNER JOIN pg_attribute AS a ON a.attrelid = c.conrelid AND cols.colnum = a.attnum
8
+ WHERE
9
+ c.contype = 'p' -- p = primary key constraint
10
+ AND c.conrelid = '${schema}.${table}'::REGCLASS limit 1) || '));' code
11
+ FROM (
12
+ SELECT ' ' || column_name || ' ' || data_type ||
13
+ coalesce('(' || character_maximum_length || ')', '') ||
14
+ case when is_nullable = 'YES' then '' else ' NOT NULL' end as column_expr
15
+ FROM information_schema.columns
16
+ WHERE table_schema = '${schema}' AND table_name = '${table}'
17
+ ORDER BY ordinal_position) column_list;`;
@@ -0,0 +1,8 @@
1
+ export default (schema: string, table: string) => `SELECT string_agg(a.attname, ', ') AS pk
2
+ FROM
3
+ pg_constraint AS c
4
+ CROSS JOIN LATERAL UNNEST(c.conkey) AS cols(colnum) -- conkey is a list of the columns of the constraint; so we split it into rows so that we can join all column numbers onto their names in pg_attribute
5
+ INNER JOIN pg_attribute AS a ON a.attrelid = c.conrelid AND cols.colnum = a.attnum
6
+ WHERE
7
+ c.contype = 'p' -- p = primary key constraint
8
+ AND c.conrelid = '${schema}.${table}'::REGCLASS;`;