@oino-ts/db-postgresql 0.0.15 → 0.0.16

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/README.md CHANGED
@@ -10,15 +10,15 @@
10
10
  # GETTING STARTED
11
11
 
12
12
  ### Setup
13
- Install the `@oino-ts/core` npm package and necessary database packages and import them in your code.
13
+ Install the `@oino-ts/db` npm package and necessary database packages and import them in your code.
14
14
  ```
15
- bun install @oino-ts/core
16
- bun install @oino-ts/bunsqlite
15
+ bun install @oino-ts/db
16
+ bun install @oino-ts/db-bunsqlite
17
17
  ```
18
18
 
19
19
  ```
20
- import { OINODb, OINOApi, OINOFactory } from "@oino-ts/core";
21
- import { OINODbBunSqlite } from "@oino-ts/bunsqlite"
20
+ import { OINODb, OINOApi, OINOFactory } from "@oino-ts/db";
21
+ import { OINODbBunSqlite } from "@oino-ts/db-bunsqlite"
22
22
  ```
23
23
 
24
24
  ### Register database and logger
@@ -51,7 +51,7 @@
51
51
  ### Write results back to HTTP Response
52
52
  The results for a GET request will contain [`OINOModelSet`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbModelSet.html) data that can be written out as JSON or CSV as needed. For other requests result is just success or error with messages.
53
53
  ```
54
- return new Response(result.modelset.writeString(OINOContentType.json))
54
+ return new Response(result.data.writeString(OINOContentType.json))
55
55
  ```
56
56
 
57
57
 
@@ -129,12 +129,13 @@
129
129
  - Bun Sqlite through Bun native implementation
130
130
  - Postgresql through [pg](https://www.npmjs.com/package/pg)-package
131
131
  - Mariadb / Mysql-support through [mariadb](https://www.npmjs.com/package/mariadb)-package
132
+ - Sql Server through [mssql](https://www.npmjs.com/package/mssql)-package
132
133
 
133
134
  ## Complex Keys
134
135
  To support tables with multipart primary keys OINO generates a composite key `_OINOID_` that is included in the result and can be used as the REST ID. For example in the example above table `OrderDetails` has two primary keys `OrderID` and `ProductID` making the `_OINOID_` of form `11077:99`.
135
136
 
136
137
  ## Power Of SQL
137
- Since OINO controls the SQL, WHERE-conditions can be defined with [`OINOSqlFilter`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlFilter.html) and order with [`OINOSqlOrder`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlOrder.html) that are passed as HTTP request parameters. No more API development where you make unique API endpoints for each filter that fetch all data with original API and filter in backend code. Every API can be filtered when and as needed without unnessecary data tranfer and utilizing SQL indexing when available.
138
+ Since OINO is just generating SQL, WHERE-conditions can be defined with [`OINOSqlFilter`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlFilter.html) and order with [`OINOSqlOrder`](https://pragmatta.github.io/oino-ts/classes/db_src.OINODbSqlOrder.html) that are passed as HTTP request parameters. No more API development where you make unique API endpoints for each filter that fetch all data with original API and filter in backend code. Every API can be filtered when and as needed without unnessecary data tranfer and utilizing SQL indexing when available.
138
139
 
139
140
  ## Swagger Support
140
141
  Swagger is great as long as the definitions are updated and with OINO you can automatically get a Swagger definition including a data model schema.
@@ -158,7 +159,7 @@
158
159
  # STATUS
159
160
  OINO is currently a hobby project which should and should considered in alpha status. That also means compatibility breaking changes can be made without prior notice when architectual issues are discovered.
160
161
 
161
- ## Beta
162
+ ## Beta
162
163
  For a beta status following milestones are planned:
163
164
 
164
165
  ### Realistic app
@@ -205,14 +206,16 @@
205
206
  # LINKS
206
207
  - [Github repository](https://github.com/pragmatta/oino-ts)
207
208
  - [NPM repository](https://www.npmjs.com/org/oino-ts)
208
-
209
+
209
210
 
210
211
  # ACKNOWLEDGEMENTS
211
212
 
212
213
  ## Libraries
213
214
  OINO uses the following open source libraries and npm packages and I would like to thank everyone for their contributions:
214
- - Postgresql support by [node-postgres package](https://www.npmjs.com/package/pg)
215
- - Mariadb / Mysql-support by [mariadb package](https://www.npmjs.com/package/mariadb)
215
+ - Postgresql [node-postgres package](https://www.npmjs.com/package/pg)
216
+ - Mariadb / Mysql [mariadb package](https://www.npmjs.com/package/mariadb)
217
+ - Sql Server [mssql package](https://www.npmjs.com/package/mssql)
218
+ - Custom base encoding [base-x package](https://www.npmjs.com/package/base-x)
216
219
 
217
220
  ## Bun
218
221
  OINO has been developed using the Bun runtime, not because of the speed improvements but for the first class Typescript support and integrated developper experience. Kudos on the bun team for making Typescript work more exiting again.
@@ -36,14 +36,25 @@ class OINOPostgresqlData extends db_1.OINODbDataSet {
36
36
  }
37
37
  _currentRow;
38
38
  _eof;
39
+ /**
40
+ * Is data set empty.
41
+ *
42
+ */
39
43
  isEmpty() {
40
44
  return (this._rows.length == 0);
41
45
  }
42
- // EOF means "there is no more content", i.e. either dataset is empty or we have moved beyond last line
46
+ /**
47
+ * Is there no more content, i.e. either dataset is empty or we have moved beyond last line
48
+ *
49
+ */
43
50
  isEof() {
44
51
  return (this._eof);
45
52
  }
46
- next() {
53
+ /**
54
+ * Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
55
+ *
56
+ */
57
+ async next() {
47
58
  // OINOLog.debug("OINODbDataSet.next", {currentRow:this._currentRow, length:this.sqlResult.data.length})
48
59
  if (this._currentRow < this._rows.length - 1) {
49
60
  this._currentRow = this._currentRow + 1;
@@ -51,8 +62,12 @@ class OINOPostgresqlData extends db_1.OINODbDataSet {
51
62
  else {
52
63
  this._eof = true;
53
64
  }
54
- return !this._eof;
65
+ return Promise.resolve(!this._eof);
55
66
  }
67
+ /**
68
+ * Gets current row of data.
69
+ *
70
+ */
56
71
  getRow() {
57
72
  if ((this._currentRow >= 0) && (this._currentRow < this._rows.length)) {
58
73
  return this._rows[this._currentRow];
@@ -67,29 +82,6 @@ class OINOPostgresqlData extends db_1.OINODbDataSet {
67
82
  *
68
83
  */
69
84
  class OINODbPostgresql extends db_1.OINODb {
70
- static table_schema_sql = `SELECT
71
- col.column_name,
72
- col.data_type,
73
- col.character_maximum_length,
74
- col.is_nullable,
75
- pk.primary_key,
76
- col.numeric_precision,
77
- col.numeric_scale,
78
- col.column_default
79
- FROM information_schema.columns col
80
- LEFT JOIN LATERAL
81
- (select kcu.column_name, 'YES' as primary_key
82
- from
83
- information_schema.table_constraints tco,
84
- information_schema.key_column_usage kcu
85
- where
86
- kcu.constraint_name = tco.constraint_name
87
- and kcu.constraint_schema = tco.constraint_schema
88
- and tco.table_name = col.table_name
89
- and tco.constraint_type = 'PRIMARY KEY'
90
- ) pk on col.column_name = pk.column_name
91
- WHERE table_name = `;
92
- // private _client:Client
93
85
  _pool;
94
86
  /**
95
87
  * Constructor of `OINODbPostgresql`
@@ -275,6 +267,31 @@ WHERE table_name = `;
275
267
  db_1.OINOBenchmark.end("OINODb", "sqlExec");
276
268
  return result;
277
269
  }
270
+ _getSchemaSql(dbName, tableName) {
271
+ const sql = `SELECT
272
+ col.column_name,
273
+ col.data_type,
274
+ col.character_maximum_length,
275
+ col.is_nullable,
276
+ pk.primary_key,
277
+ col.numeric_precision,
278
+ col.numeric_scale,
279
+ col.column_default
280
+ FROM information_schema.columns col
281
+ LEFT JOIN LATERAL
282
+ (select kcu.column_name, 'YES' as primary_key
283
+ from
284
+ information_schema.table_constraints tco,
285
+ information_schema.key_column_usage kcu
286
+ where
287
+ kcu.constraint_name = tco.constraint_name
288
+ and kcu.constraint_schema = tco.constraint_schema
289
+ and tco.table_name = col.table_name
290
+ and tco.constraint_type = 'PRIMARY KEY'
291
+ ) pk on col.column_name = pk.column_name
292
+ WHERE col.table_catalog = '${dbName}' AND col.table_name = '${tableName}'`;
293
+ return sql;
294
+ }
278
295
  /**
279
296
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
280
297
  * the model.
@@ -283,7 +300,7 @@ WHERE table_name = `;
283
300
  *
284
301
  */
285
302
  async initializeApiDatamodel(api) {
286
- const res = await this.sqlSelect(OINODbPostgresql.table_schema_sql + "'" + api.params.tableName.toLowerCase() + "';");
303
+ const res = await this.sqlSelect(this._getSchemaSql(this._params.database, api.params.tableName.toLowerCase()));
287
304
  // OINOLog.debug("OINODbPostgresql.initializeApiDatamodel: table description ", {res: res })
288
305
  while (!res.isEof()) {
289
306
  const row = res.getRow();
@@ -329,7 +346,7 @@ WHERE table_name = `;
329
346
  api.datamodel.addField(new db_1.OINOStringDataField(this, field_name, sql_type, field_params, 0));
330
347
  }
331
348
  }
332
- res.next();
349
+ await res.next();
333
350
  }
334
351
  db_1.OINOLog.debug("OINODbPostgresql.initializeDatasetModel:\n" + api.datamodel.printDebug("\n"));
335
352
  return Promise.resolve();
@@ -33,14 +33,25 @@ class OINOPostgresqlData extends OINODbDataSet {
33
33
  }
34
34
  _currentRow;
35
35
  _eof;
36
+ /**
37
+ * Is data set empty.
38
+ *
39
+ */
36
40
  isEmpty() {
37
41
  return (this._rows.length == 0);
38
42
  }
39
- // EOF means "there is no more content", i.e. either dataset is empty or we have moved beyond last line
43
+ /**
44
+ * Is there no more content, i.e. either dataset is empty or we have moved beyond last line
45
+ *
46
+ */
40
47
  isEof() {
41
48
  return (this._eof);
42
49
  }
43
- next() {
50
+ /**
51
+ * Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
52
+ *
53
+ */
54
+ async next() {
44
55
  // OINOLog.debug("OINODbDataSet.next", {currentRow:this._currentRow, length:this.sqlResult.data.length})
45
56
  if (this._currentRow < this._rows.length - 1) {
46
57
  this._currentRow = this._currentRow + 1;
@@ -48,8 +59,12 @@ class OINOPostgresqlData extends OINODbDataSet {
48
59
  else {
49
60
  this._eof = true;
50
61
  }
51
- return !this._eof;
62
+ return Promise.resolve(!this._eof);
52
63
  }
64
+ /**
65
+ * Gets current row of data.
66
+ *
67
+ */
53
68
  getRow() {
54
69
  if ((this._currentRow >= 0) && (this._currentRow < this._rows.length)) {
55
70
  return this._rows[this._currentRow];
@@ -64,29 +79,6 @@ class OINOPostgresqlData extends OINODbDataSet {
64
79
  *
65
80
  */
66
81
  export class OINODbPostgresql extends OINODb {
67
- static table_schema_sql = `SELECT
68
- col.column_name,
69
- col.data_type,
70
- col.character_maximum_length,
71
- col.is_nullable,
72
- pk.primary_key,
73
- col.numeric_precision,
74
- col.numeric_scale,
75
- col.column_default
76
- FROM information_schema.columns col
77
- LEFT JOIN LATERAL
78
- (select kcu.column_name, 'YES' as primary_key
79
- from
80
- information_schema.table_constraints tco,
81
- information_schema.key_column_usage kcu
82
- where
83
- kcu.constraint_name = tco.constraint_name
84
- and kcu.constraint_schema = tco.constraint_schema
85
- and tco.table_name = col.table_name
86
- and tco.constraint_type = 'PRIMARY KEY'
87
- ) pk on col.column_name = pk.column_name
88
- WHERE table_name = `;
89
- // private _client:Client
90
82
  _pool;
91
83
  /**
92
84
  * Constructor of `OINODbPostgresql`
@@ -272,6 +264,31 @@ WHERE table_name = `;
272
264
  OINOBenchmark.end("OINODb", "sqlExec");
273
265
  return result;
274
266
  }
267
+ _getSchemaSql(dbName, tableName) {
268
+ const sql = `SELECT
269
+ col.column_name,
270
+ col.data_type,
271
+ col.character_maximum_length,
272
+ col.is_nullable,
273
+ pk.primary_key,
274
+ col.numeric_precision,
275
+ col.numeric_scale,
276
+ col.column_default
277
+ FROM information_schema.columns col
278
+ LEFT JOIN LATERAL
279
+ (select kcu.column_name, 'YES' as primary_key
280
+ from
281
+ information_schema.table_constraints tco,
282
+ information_schema.key_column_usage kcu
283
+ where
284
+ kcu.constraint_name = tco.constraint_name
285
+ and kcu.constraint_schema = tco.constraint_schema
286
+ and tco.table_name = col.table_name
287
+ and tco.constraint_type = 'PRIMARY KEY'
288
+ ) pk on col.column_name = pk.column_name
289
+ WHERE col.table_catalog = '${dbName}' AND col.table_name = '${tableName}'`;
290
+ return sql;
291
+ }
275
292
  /**
276
293
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
277
294
  * the model.
@@ -280,7 +297,7 @@ WHERE table_name = `;
280
297
  *
281
298
  */
282
299
  async initializeApiDatamodel(api) {
283
- const res = await this.sqlSelect(OINODbPostgresql.table_schema_sql + "'" + api.params.tableName.toLowerCase() + "';");
300
+ const res = await this.sqlSelect(this._getSchemaSql(this._params.database, api.params.tableName.toLowerCase()));
284
301
  // OINOLog.debug("OINODbPostgresql.initializeApiDatamodel: table description ", {res: res })
285
302
  while (!res.isEof()) {
286
303
  const row = res.getRow();
@@ -326,7 +343,7 @@ WHERE table_name = `;
326
343
  api.datamodel.addField(new OINOStringDataField(this, field_name, sql_type, field_params, 0));
327
344
  }
328
345
  }
329
- res.next();
346
+ await res.next();
330
347
  }
331
348
  OINOLog.debug("OINODbPostgresql.initializeDatasetModel:\n" + api.datamodel.printDebug("\n"));
332
349
  return Promise.resolve();
@@ -4,7 +4,6 @@ import { OINODb, OINODbParams, OINODbDataSet, OINODbApi, OINODataCell } from "@o
4
4
  *
5
5
  */
6
6
  export declare class OINODbPostgresql extends OINODb {
7
- private static table_schema_sql;
8
7
  private _pool;
9
8
  /**
10
9
  * Constructor of `OINODbPostgresql`
@@ -65,6 +64,7 @@ export declare class OINODbPostgresql extends OINODb {
65
64
  *
66
65
  */
67
66
  sqlExec(sql: string): Promise<OINODbDataSet>;
67
+ private _getSchemaSql;
68
68
  /**
69
69
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
70
70
  * the model.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/db-postgresql",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "OINO TS package for using Postgresql databases.",
5
5
  "author": "Matias Kiviniemi (pragmatta)",
6
6
  "license": "MPL-2.0",
@@ -20,7 +20,7 @@
20
20
  "module": "./dist/esm/index.js",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "dependencies": {
23
- "@oino-ts/db": "^0.0.15",
23
+ "@oino-ts/db": "^0.0.16",
24
24
  "pg": "^8.11.3"
25
25
  },
26
26
  "devDependencies": {
@@ -38,25 +38,41 @@ class OINOPostgresqlData extends OINODbDataSet {
38
38
  }
39
39
  private _currentRow: number
40
40
  private _eof: boolean
41
+
42
+ /**
43
+ * Is data set empty.
44
+ *
45
+ */
41
46
  isEmpty():boolean {
42
47
  return (this._rows.length == 0)
43
48
  }
44
49
 
45
- // EOF means "there is no more content", i.e. either dataset is empty or we have moved beyond last line
50
+ /**
51
+ * Is there no more content, i.e. either dataset is empty or we have moved beyond last line
52
+ *
53
+ */
46
54
  isEof():boolean {
47
55
  return (this._eof)
48
56
  }
49
57
 
50
- next():boolean {
58
+ /**
59
+ * Attempts to moves dataset to the next row, possibly waiting for more data to become available. Returns !isEof().
60
+ *
61
+ */
62
+ async next():Promise<boolean> {
51
63
  // OINOLog.debug("OINODbDataSet.next", {currentRow:this._currentRow, length:this.sqlResult.data.length})
52
64
  if (this._currentRow < this._rows.length-1) {
53
65
  this._currentRow = this._currentRow + 1
54
66
  } else {
55
67
  this._eof = true
56
68
  }
57
- return !this._eof
69
+ return Promise.resolve(!this._eof)
58
70
  }
59
71
 
72
+ /**
73
+ * Gets current row of data.
74
+ *
75
+ */
60
76
  getRow(): OINODataRow {
61
77
  if ((this._currentRow >=0) && (this._currentRow < this._rows.length)) {
62
78
  return this._rows[this._currentRow]
@@ -72,31 +88,6 @@ class OINOPostgresqlData extends OINODbDataSet {
72
88
  */
73
89
  export class OINODbPostgresql extends OINODb {
74
90
 
75
- private static table_schema_sql:string =
76
- `SELECT
77
- col.column_name,
78
- col.data_type,
79
- col.character_maximum_length,
80
- col.is_nullable,
81
- pk.primary_key,
82
- col.numeric_precision,
83
- col.numeric_scale,
84
- col.column_default
85
- FROM information_schema.columns col
86
- LEFT JOIN LATERAL
87
- (select kcu.column_name, 'YES' as primary_key
88
- from
89
- information_schema.table_constraints tco,
90
- information_schema.key_column_usage kcu
91
- where
92
- kcu.constraint_name = tco.constraint_name
93
- and kcu.constraint_schema = tco.constraint_schema
94
- and tco.table_name = col.table_name
95
- and tco.constraint_type = 'PRIMARY KEY'
96
- ) pk on col.column_name = pk.column_name
97
- WHERE table_name = `
98
-
99
- // private _client:Client
100
91
  private _pool:Pool
101
92
 
102
93
  /**
@@ -292,6 +283,33 @@ WHERE table_name = `
292
283
  return result
293
284
  }
294
285
 
286
+ private _getSchemaSql(dbName:string, tableName:string):string {
287
+ const sql =
288
+ `SELECT
289
+ col.column_name,
290
+ col.data_type,
291
+ col.character_maximum_length,
292
+ col.is_nullable,
293
+ pk.primary_key,
294
+ col.numeric_precision,
295
+ col.numeric_scale,
296
+ col.column_default
297
+ FROM information_schema.columns col
298
+ LEFT JOIN LATERAL
299
+ (select kcu.column_name, 'YES' as primary_key
300
+ from
301
+ information_schema.table_constraints tco,
302
+ information_schema.key_column_usage kcu
303
+ where
304
+ kcu.constraint_name = tco.constraint_name
305
+ and kcu.constraint_schema = tco.constraint_schema
306
+ and tco.table_name = col.table_name
307
+ and tco.constraint_type = 'PRIMARY KEY'
308
+ ) pk on col.column_name = pk.column_name
309
+ WHERE col.table_catalog = '${dbName}' AND col.table_name = '${tableName}'`
310
+ return sql
311
+ }
312
+
295
313
  /**
296
314
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
297
315
  * the model.
@@ -301,7 +319,7 @@ WHERE table_name = `
301
319
  */
302
320
  async initializeApiDatamodel(api:OINODbApi): Promise<void> {
303
321
 
304
- const res:OINODbDataSet = await this.sqlSelect(OINODbPostgresql.table_schema_sql + "'" + api.params.tableName.toLowerCase() + "';")
322
+ const res:OINODbDataSet = await this.sqlSelect(this._getSchemaSql(this._params.database, api.params.tableName.toLowerCase()))
305
323
  // OINOLog.debug("OINODbPostgresql.initializeApiDatamodel: table description ", {res: res })
306
324
  while (!res.isEof()) {
307
325
  const row:OINODataRow = res.getRow()
@@ -346,7 +364,7 @@ WHERE table_name = `
346
364
  api.datamodel.addField(new OINOStringDataField(this, field_name, sql_type, field_params, 0))
347
365
  }
348
366
  }
349
- res.next()
367
+ await res.next()
350
368
  }
351
369
  OINOLog.debug("OINODbPostgresql.initializeDatasetModel:\n" + api.datamodel.printDebug("\n"))
352
370
  return Promise.resolve()