db-crud-api 0.1.9 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -22,3 +22,16 @@
22
22
 
23
23
  Bug fix:
24
24
  - update function crash with date value
25
+ ## v0.1.9 (2024-03-12)
26
+
27
+ Added:
28
+ - execute store procedure
29
+ ## v0.2.0 (2024-04-02)
30
+
31
+ Changes:
32
+ - parameters position have been change for some api
33
+ Added:
34
+ - batch job that run multiple instructions
35
+ ## v0.2.1 (2024-12-05)
36
+
37
+ Refresh dependency
package/README.md CHANGED
@@ -61,13 +61,13 @@
61
61
  const apiExecuteSP = apiFactory.newExecuteApi("my_storeproc @Company, @OrderNumber"); // execute my_storeproc
62
62
 
63
63
  console.log(await apiOrder.getById("xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx"));
64
+ console.log(await apiOrder.getById("xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx", {get: {fields: ["Id", "OrderNumber", "OrderTotal"]}}));
64
65
  console.log(await apiOrder.getByFilter({get: {filters: ["OrderType in ('P', 'A')", "and", "OrderDate > '2022-12-01'"]}})); // get filterd rows
65
66
  console.log(await apiOrder.getByFilter()); // this get all rows
66
- console.log(await apiOrderDetail.patchById("xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx", {patch: {sets: {ItemRef: "2024-TX-0001", ItemDate: "2024-01-31"}}})); // change some fields
67
+ console.log(await apiOrderDetail.patchById({patch: {sets: {ItemRef: "2024-TX-0001", ItemDate: "2024-01-31"}}}, "xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx")); // change some fields
67
68
  console.log(await apiOrderDetail.patchByFilter({patch: {sets: {LastUpdate: "2023-04-30"}, filters: ["OrderId: 'xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx'"]}})); // change by filter
68
69
  console.log(await apiOrderDetail.deleteById("xxxxx-xxxxx-xxxxxxxxxxxx-xxxxxx")); // delete row by Id
69
70
  console.log(await apiOrderDetail.deleteByFilter({delete: {filters: ["ItemType in ('X', 'W')", "and", "ItemDate > '2022-12-01'"]}})); // delete filterd rows
70
- console.log(await apiOrderDetail.deleteByFilter({delete: {filters: ["ItemType in ('X', 'W')", "and", "ItemDate > '2022-12-01'"]}})); // delete filterd rows
71
71
  console.log(await apiExecuteSP.execute({params: {Company: "XXX", OrderNumber: "12345"}}})); // execute
72
72
  ```
73
73
 
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ // Import modules
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ import * as dbOpe from './db-operations.js';
6
+
7
+ export default class apiBatch {
8
+
9
+ #operations = [];
10
+ #dbOperations = [];
11
+ #useTransaction = false;
12
+
13
+ constructor(useTransaction) {
14
+ if (typeof(useTransaction) === "boolean") this.#useTransaction = useTransaction;
15
+ }
16
+
17
+ get useTransaction() { return this.#useTransaction; }
18
+ set useTransaction(useTransaction) { if (typeof(useTransaction) === "boolean") this.#useTransaction = useTransaction; }
19
+
20
+ // reset Batch
21
+ #resetBatch() {
22
+ this.#operations = [];
23
+ this.#dbOperations = [];
24
+ }
25
+
26
+ // run batch
27
+ async runBatch() {
28
+
29
+ if (this.#dbOperations.length == 0) { throw new Error("runBatch: there are not operations in this batch.") }
30
+
31
+ // prepare transaction
32
+ if (this.#useTransaction) {
33
+ const _reqOpe_begin = {begin: {}};
34
+ const _dbOpe_begin = dbOpe.prepareBegin(this.#dbOperations[0].connection, _reqOpe_begin);
35
+ this.#dbOperations.unshift(_dbOpe_begin);
36
+ this.#operations.unshift(_reqOpe_begin);
37
+
38
+ const _reqOpe_commit = {commit: {}};
39
+ const _dbOpe_commit = dbOpe.prepareCommit(this.#dbOperations[0].connection, _reqOpe_commit);
40
+ this.#dbOperations.push(_dbOpe_commit);
41
+ this.#operations.push(_reqOpe_commit);
42
+ }
43
+
44
+ // run
45
+ const _return = await dbOpe.runQuery(this.#dbOperations);
46
+
47
+ // reset
48
+ this.#resetBatch();
49
+
50
+ return _return;
51
+ }
52
+
53
+ // execute
54
+ execute(command, reqOpe) {
55
+ const _schema = dbOpe.prepareSchema(command, dbOpe.objectType.procedure);
56
+ const _connection = dbOpe.prepareConnection(_schema);
57
+ this.#dbOperations.push(dbOpe.prepareExecute(_schema, _connection, reqOpe));
58
+ this.#operations.push(reqOpe);
59
+ return;
60
+ }
61
+
62
+ // Get by id
63
+ // note that getById when executed in a batch, return an array instead of single object
64
+ getById(tablePath, id, reqOpe) {
65
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
66
+ const _connection = dbOpe.prepareConnection(_schema);
67
+ this.#dbOperations.push(dbOpe.prepareGetById(_schema, _connection, reqOpe, id));
68
+ this.#operations.push(reqOpe);
69
+ return;
70
+ }
71
+
72
+ // Get by filter
73
+ getByFilter(tablePath, reqOpe) {
74
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
75
+ const _connection = dbOpe.prepareConnection(_schema);
76
+ this.#dbOperations.push(dbOpe.prepareGet(_schema, _connection, reqOpe));
77
+ this.#operations.push(reqOpe);
78
+ return;
79
+ }
80
+
81
+ // Add
82
+ put(tablePath, reqOpe) {
83
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
84
+ const _connection = dbOpe.prepareConnection(_schema);
85
+ const _dbOpe = dbOpe.preparePut(_schema, _connection, reqOpe);
86
+ if (_dbOpe.put.sets && _schema.autoId === true) // automatic Id
87
+ if (!Object.keys(_dbOpe.put.sets).find(key => key.toUpperCase() === (dbOpe.idField(_schema)).toUpperCase()))
88
+ _dbOpe.put.sets[dbOpe.idField(_schema)] = uuidv4(); // automatic Id via uuidv4
89
+ this.#dbOperations.push(_dbOpe);
90
+ this.#operations.push(reqOpe);
91
+ return;
92
+ }
93
+
94
+ // Add by Id
95
+ putById(tablePath, reqOpe, id) {
96
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
97
+ const _connection = dbOpe.prepareConnection(_schema);
98
+ this.#dbOperations.push(dbOpe.preparePutById(_schema, _connection, reqOpe, id));
99
+ this.#operations.push(reqOpe);
100
+ return;
101
+ }
102
+
103
+ // Delete by id
104
+ delById(tablePath, id) {
105
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
106
+ const _connection = dbOpe.prepareConnection(_schema);
107
+ this.#dbOperations.push(dbOpe.prepareDeleteById(_schema, _connection, id));
108
+ this.#operations.push({});
109
+ return;
110
+ }
111
+
112
+ // Delete by filters
113
+ delByFilter(tablePath, reqOpe) {
114
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
115
+ const _connection = dbOpe.prepareConnection(_schema);
116
+ this.#dbOperations.push(dbOpe.prepareDelete(_schema, _connection, reqOpe));
117
+ this.#operations.push(reqOpe);
118
+ return;
119
+ }
120
+
121
+ // Patch (update) by id
122
+ patchById(tablePath, reqOpe, id) {
123
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
124
+ const _connection = dbOpe.prepareConnection(_schema);
125
+ this.#dbOperations.push(dbOpe.preparePatchById(_schema, _connection, reqOpe, id));
126
+ this.#operations.push(reqOpe);
127
+ return;
128
+ }
129
+
130
+ // Patch (update) by filters
131
+ patchByFilter(tablePath, reqOpe) {
132
+ const _schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
133
+ const _connection = dbOpe.prepareConnection(_schema);
134
+ this.#dbOperations.push(dbOpe.preparePatch(_schema, _connection, reqOpe));
135
+ this.#operations.push(reqOpe);
136
+ return;
137
+ }
138
+
139
+ }
@@ -9,17 +9,17 @@ export default class apiExecute {
9
9
  #connection;
10
10
 
11
11
  constructor(command) {
12
- this.#schema = dbOpe.prepareSchema(command, "SP");
12
+ this.#schema = dbOpe.prepareSchema(command, dbOpe.objectType.procedure);
13
13
  this.#connection = dbOpe.prepareConnection(this.#schema);
14
14
  }
15
15
 
16
16
  get schema() { return this.#schema; }
17
17
  get connection() { return this.#connection; }
18
18
 
19
- // Post (any operation like get/put/patch/delete...)
19
+ // execute
20
20
  async execute(reqOpe) {
21
- const _dbOpe = dbOpe.prepareExecute(this.#schema, reqOpe);
22
- return await dbOpe.runQuery(this.#connection, _dbOpe);
21
+ const _dbOpe = dbOpe.prepareExecute(this.#schema, this.#connection, reqOpe);
22
+ return await dbOpe.runQuery(_dbOpe);
23
23
  }
24
24
 
25
25
  }
@@ -4,6 +4,7 @@ import * as dbOpe from "./db-operations.js"
4
4
  import apiFull from "./api-full.js"
5
5
  import apiRO from "./api-ro.js"
6
6
  import apiExecute from "./api-execute.js"
7
+ import apiBatch from "./api-batch.js"
7
8
 
8
9
  export function newFullApi(tablePath) {
9
10
  return new apiFull(tablePath);
@@ -17,6 +18,10 @@ export function newExecuteApi(command) {
17
18
  return new apiExecute(command);
18
19
  }
19
20
 
21
+ export function newBatchApi(useTransaction) {
22
+ return new apiBatch(useTransaction);
23
+ }
24
+
20
25
  export function closeAllDbConnections() {
21
26
  return dbOpe.closeAllConnections();
22
27
  }
package/lib/api-full.js CHANGED
@@ -10,93 +10,87 @@ export default class apiFull {
10
10
  #connection;
11
11
 
12
12
  constructor(tablePath) {
13
- this.#schema = dbOpe.prepareTableSchema(tablePath);
13
+ this.#schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
14
14
  this.#connection = dbOpe.prepareConnection(this.#schema);
15
15
  }
16
16
 
17
17
  get schema() { return this.#schema; }
18
18
  get connection() { return this.#connection; }
19
19
 
20
- // Run query
21
- // async runOpe(_dbOpe) {
22
- // return await dbOpe.runQuery(this.#connection, _dbOpe);
23
- // }
24
-
25
20
  // Get by id
26
21
  async getById(id, reqOpe) {
27
- const _dbOpe = dbOpe.prepareGetById(this.#schema, id, reqOpe);
28
- const result = await dbOpe.runQuery(this.#connection, _dbOpe);
22
+ const _dbOpe = dbOpe.prepareGetById(this.#schema, this.#connection, reqOpe, id);
23
+ const result = await dbOpe.runQuery(_dbOpe);
29
24
  return Array.isArray(result) ? result[0] : result;
30
-
31
25
  }
32
26
 
33
27
  // Get by filter
34
28
  async getByFilter(reqOpe) {
35
- const _dbOpe = dbOpe.prepareGet(this.#schema, reqOpe);
36
- return await dbOpe.runQuery(this.#connection, _dbOpe);
29
+ const _dbOpe = dbOpe.prepareGet(this.#schema, this.#connection, reqOpe);
30
+ return await dbOpe.runQuery(_dbOpe);
37
31
  }
38
32
 
39
33
  // Post by id (any operation like get/put/patch/delete...)
40
- async postById(id, reqOpe) {
41
- const _dbOpe = dbOpe.prepareRunById(this.#schema, id, reqOpe);
42
- return await dbOpe.runQuery(this.#connection, _dbOpe);
34
+ async postById(reqOpe, id) {
35
+ const _dbOpe = dbOpe.prepareRunById(this.#schema, this.#connection, reqOpe, id);
36
+ return await dbOpe.runQuery(_dbOpe);
43
37
  }
44
38
 
45
39
  // Post (any operation like get/put/patch/delete...)
46
40
  async post(reqOpe) {
47
- const _dbOpe = dbOpe.prepareRun(this.#schema, reqOpe);
48
- return await dbOpe.runQuery(this.#connection, _dbOpe);
41
+ const _dbOpe = dbOpe.prepareRun(this.#schema, this.#connection, reqOpe);
42
+ return await dbOpe.runQuery(_dbOpe);
49
43
  }
50
44
 
51
45
  // Add item
52
46
  async put(reqOpe) {
53
- const _dbOpe = dbOpe.preparePut(this.#schema, reqOpe);
47
+ const _dbOpe = dbOpe.preparePut(this.#schema, this.#connection, reqOpe);
54
48
  if (_dbOpe.put.sets) {
55
49
  if (this.#schema.autoId === true) // automatic Id
56
50
  if (!Object.keys(_dbOpe.put.sets).find(key => key.toUpperCase() === (dbOpe.idField(this.#schema)).toUpperCase())) {
57
51
  _dbOpe.put.sets[dbOpe.idField(this.#schema)] = uuidv4(); // automatic Id via uuidv4
58
52
  }
59
53
  }
60
- await dbOpe.runQuery(this.#connection, _dbOpe);
54
+ await dbOpe.runQuery(_dbOpe);
61
55
  return _dbOpe.put.sets;
62
56
  }
63
57
 
64
58
  // Add by Id
65
- async putById(id, reqOpe) {
66
- const _dbOpe = dbOpe.preparePutById(this.#schema, id, reqOpe);
67
- await dbOpe.runQuery(this.#connection, _dbOpe);
59
+ async putById(reqOpe, id) {
60
+ const _dbOpe = dbOpe.preparePutById(this.#schema, this.#connection, reqOpe, id);
61
+ await dbOpe.runQuery(_dbOpe);
68
62
  return _dbOpe.put.sets;
69
63
  }
70
64
 
71
65
  // New (put + getById)
72
66
  async new(reqOpe) {
73
67
  const obj = await this.put(reqOpe);
74
- const _return = await this.getById(obj[dbOpe.idField(this.#schema)], undefined);
68
+ const _return = await this.getById(obj[dbOpe.idField(this.#schema)]);
75
69
  return _return;
76
70
  }
77
71
 
78
72
  // Delete by id
79
73
  async delById(id) {
80
- const _dbOpe = dbOpe.prepareDeleteById(this.#schema, id);
81
- return await dbOpe.runQuery(this.#connection, _dbOpe);
74
+ const _dbOpe = dbOpe.prepareDeleteById(this.#schema, this.#connection, id);
75
+ return await dbOpe.runQuery(_dbOpe);
82
76
  }
83
77
 
84
78
  // Delete by filters
85
79
  async delByFilter(reqOpe) {
86
- const _dbOpe = dbOpe.prepareDelete(this.#schema, reqOpe);
87
- return await dbOpe.runQuery(this.#connection, _dbOpe);
80
+ const _dbOpe = dbOpe.prepareDelete(this.#schema, this.#connection, reqOpe);
81
+ return await dbOpe.runQuery(_dbOpe);
88
82
  }
89
83
 
90
84
  // Patch (update) by id
91
- async patchById(id, reqOpe) {
92
- const _dbOpe = dbOpe.preparePatchById(this.#schema, id, reqOpe);
93
- return await dbOpe.runQuery(this.#connection, _dbOpe);
85
+ async patchById(reqOpe, id) {
86
+ const _dbOpe = dbOpe.preparePatchById(this.#schema, this.#connection, reqOpe, id);
87
+ return await dbOpe.runQuery(_dbOpe);
94
88
  }
95
89
 
96
90
  // Patch (update) by filters
97
91
  async patchByFilter(reqOpe) {
98
- const _dbOpe = dbOpe.preparePatch(this.#schema, reqOpe);
99
- return await dbOpe.runQuery(this.#connection, _dbOpe);
92
+ const _dbOpe = dbOpe.preparePatch(this.#schema, this.#connection, reqOpe);
93
+ return await dbOpe.runQuery(_dbOpe);
100
94
  }
101
95
 
102
96
  }
package/lib/api-ro.js CHANGED
@@ -9,7 +9,7 @@ export default class apiRO {
9
9
  #connection;
10
10
 
11
11
  constructor(tablePath) {
12
- this.#schema = dbOpe.prepareTableSchema(tablePath);
12
+ this.#schema = dbOpe.prepareSchema(tablePath, dbOpe.objectType.table);
13
13
  this.#connection = dbOpe.prepareConnection(this.#schema);
14
14
  }
15
15
 
@@ -23,16 +23,16 @@ export default class apiRO {
23
23
 
24
24
  // Get by id
25
25
  async getById(id, reqOpe) {
26
- const _dbOpe = dbOpe.prepareGetById(this.#schema, id, reqOpe);
27
- const result = await dbOpe.runQuery(this.#connection, _dbOpe);
26
+ const _dbOpe = dbOpe.prepareGetById(this.#schema, this.#connection, reqOpe, id);
27
+ const result = await dbOpe.runQuery(_dbOpe);
28
28
  return Array.isArray(result) ? result[0] : result;
29
29
 
30
30
  }
31
31
 
32
32
  // Get by filter
33
33
  async getByFilter(reqOpe) {
34
- const _dbOpe = dbOpe.prepareGet(this.#schema, reqOpe);
35
- return await dbOpe.runQuery(this.#connection, _dbOpe);
34
+ const _dbOpe = dbOpe.prepareGet(this.#schema, this.#connection, reqOpe);
35
+ return await dbOpe.runQuery(_dbOpe);
36
36
  }
37
37
 
38
38
  }
@@ -6,35 +6,49 @@ import * as mssql from './mssql.js';
6
6
 
7
7
  // Common
8
8
  const defautlFields = ['*'];
9
- const c_ServerType_mssql = "ms-sql";
9
+ export const serverType = Object.freeze({ mssql: 'ms-sql', mysql: 'my-sql', mongodb: 'mongo-db' });
10
+ export const objectType = Object.freeze({ table: 'T', procedure: 'P' });
10
11
 
11
12
  // Exported functions
12
13
  export function idField(tSchema) {
13
14
  return tSchema.table?.idField ?? 'id';
14
15
  }
15
16
 
16
- export async function runQuery(connection, dbOpes) {
17
- if (connection.serverType === c_ServerType_mssql) {
18
- const sqlresult = await mssql.query(connection, dbOpes);
17
+ export async function runQuery(dbOpes) {
18
+
19
+ // all connections must have same id
20
+ const _connection = Array.isArray(dbOpes) ? dbOpes[0].connection : dbOpes.connection;
21
+ if (Array.isArray(dbOpes)) {
22
+ for (let i = 1; i < dbOpes.length; i++) {
23
+ if (dbOpes[i].connection?.id !== _connection.id) throw new TypeError('runQuery: for multiple operations, connection must be the same');
24
+ }
25
+ }
26
+
27
+ // MSSQL
28
+ if (_connection.serverType === serverType.mssql) {
29
+ const sqlresult = await mssql.query(_connection, dbOpes);
19
30
  ////mssql.closeConnection(connection);
20
- if (sqlresult.recordsets.length === 0) { return; }
21
- if (sqlresult.recordsets.length === 1) { return sqlresult.recordsets[0]; }
22
- else { return sqlresult.recordsets; }
31
+ if (sqlresult.recordsets.length === 0) return;
32
+ if (sqlresult.recordsets.length === 1) return sqlresult.recordsets[0];
33
+ else return sqlresult.recordsets;
23
34
  }
24
- throw new TypeError('server type not supported');
35
+
36
+ // server type not supported
37
+ else throw new TypeError('server type not supported');
38
+
25
39
  }
26
40
 
27
- export function prepareConnection(tSchema) {
28
- if (!tSchema.server.type || tSchema.server.type === c_ServerType_mssql) { // mssql is also the default
29
- let _return = mssql.prepareConnection(tSchema);
30
- _return.serverType = c_ServerType_mssql; // append 'serverType' to connection
41
+ export function prepareConnection(schema) {
42
+ if (!schema.server.type || schema.server.type === serverType.mssql) { // mssql is also the default
43
+ const _return = mssql.prepareConnection(schema);
44
+ _return.serverType = serverType.mssql; // append 'serverType' to connection
31
45
  return _return;
32
46
  }
33
47
  throw new TypeError('server type not supported');
34
48
  }
35
49
 
36
50
  export function closeConnection(connection) {
37
- if (connection.serverType === c_ServerType_mssql) { return mssql.closeConnection(connection); }
51
+ if (connection.serverType === serverType.mssql) { return mssql.closeConnection(connection); }
38
52
  }
39
53
 
40
54
  export function closeAllConnections() {
@@ -49,11 +63,11 @@ export function toStringValue(value) {
49
63
 
50
64
  export function prepareSchema(obj, objType) {
51
65
  // eg. obj = 'systemName.dbName.tableName' or 'dbName.tableName' or 'tablename' or 'systemNme..tableName'
52
- // obj = 'systemName.dbName.spName @param1, @param2 ' or 'dbName.speName @param1' or 'spName' or 'systemNme..spName'
53
- // objType = "T" or "SP" (Table or StoreProcedure)
66
+ // obj = 'systemName.dbName.spName @param1, @param2 ' or 'dbName.spName @param1' or 'spName' or 'systemNme..spName'
67
+ // objType = 'objectType.' (Table or StoreProcedure)
54
68
 
55
69
  if (obj == undefined || typeof obj !== 'string') throw new TypeError('prepareSchema: wrong obj');
56
- if (objType !== undefined && objType !== 'T' && objType !== 'SP') throw new TypeError('prepareSchema: wrong objType, must be "T" or "SP"');
70
+ if (objType !== undefined && objType !== objectType.table && objType !== objectType.procedure) throw new TypeError(`prepareSchema: wrong objType, must be ${objectType.join(', ')}`);
57
71
  const objPath = obj.trimStart().split(' ')[0];
58
72
 
59
73
  // split objPath to serverName,dbName,objName
@@ -97,7 +111,7 @@ export function prepareSchema(obj, objType) {
97
111
  if (!schema.servers[serverName].databases[dbName].realName) { schema.servers[serverName].databases[dbName].realName = dbName } // add realName
98
112
 
99
113
  // table
100
- if (objType === "T" || objType == undefined) {
114
+ if (objType === objectType.table || objType == undefined) {
101
115
  if (!objName || objName.length == 0) {
102
116
  if (!schema.servers[serverName].databases[dbName] || !Object.keys(schema.servers[serverName].databases[dbName].tables)[0]) throw new TypeError('missing default table in dbSchema');
103
117
  objName = Object.keys(schema.servers[serverName].databases[dbName].tables)[0];
@@ -110,7 +124,7 @@ export function prepareSchema(obj, objType) {
110
124
  }
111
125
 
112
126
  // store procedure
113
- if (objType === "SP") {
127
+ if (objType === objectType.procedure) {
114
128
  if (!objName || objName.length == 0) {
115
129
  if (!schema.servers[serverName].databases[dbName] || !Object.keys(schema.servers[serverName].databases[dbName].procedures)[0]) throw new TypeError('missing default procedure in dbSchema');
116
130
  objName = Object.keys(schema.servers[serverName].databases[dbName].procedures)[0];
@@ -122,36 +136,36 @@ export function prepareSchema(obj, objType) {
122
136
  if (!schema.servers[serverName].databases[dbName].procedures[objName].realName) { schema.servers[serverName].databases[dbName].procedures[objName].realName = objName } // add realName
123
137
  }
124
138
 
125
- // return tSchema
139
+ // return Schema
126
140
  return {
127
- table: (objType == undefined || objType === 'T') ? schema.servers[serverName].databases[dbName].tables[objName] : undefined,
128
- procedure: (objType === 'SP') ? schema.servers[serverName].databases[dbName].procedures[objName] : undefined,
141
+ table: (objType == undefined || objType === objectType.table) ? schema.servers[serverName].databases[dbName].tables[objName] : undefined,
142
+ procedure: (objType === objectType.procedure) ? schema.servers[serverName].databases[dbName].procedures[objName] : undefined,
129
143
  database: schema.servers[serverName].databases[dbName],
130
144
  server: schema.servers[serverName]
131
145
  }
132
146
 
133
147
  }
134
148
 
135
- export function prepareTableSchema(tablePath) {
149
+ //export function prepareTableSchema(tablePath) {
136
150
  // alias for prepareSchema (will be removed soon)
137
- return prepareSchema(tablePath, "T")
138
- }
151
+ // return prepareSchema(tablePath, objectType.table)
152
+ //}
139
153
 
140
- export function prepareRun(tSchema, reqOpe) {
141
- let _reqOpe = [];
142
- let _result = [];
154
+ export function prepareRun(tSchema, connection, reqOpe) {
155
+ const _reqOpe = [];
156
+ const _result = [];
143
157
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
144
158
  else _reqOpe.push(reqOpe);
145
159
  _reqOpe.forEach(function (_ope) {
146
- if (_ope?.get) _result.push(prepareGet(tSchema, _ope));
147
- else if (_ope?.patch) _result.push(preparePatch(tSchema, _ope));
148
- else if (_ope?.put) _result.push(preparePut(tSchema, _ope));
149
- else if (_ope?.delete) _result.push(prepareDelete(tSchema, _ope));
150
- else if (_ope?.execute) _result.push(prepareExecute(_ope));
151
- else if (_ope?.begin) _result.push(prepareBegin(_ope));
152
- else if (_ope?.commit) _result.push(prepareCommit(_ope));
153
- else if (_ope?.rollback) _result.push(prepareRollback(_ope));
154
- else if (_ope?.passthrough) _result.push(preparePassthrough(_ope));
160
+ if (_ope?.get) _result.push(prepareGet(tSchema, connection, _ope));
161
+ else if (_ope?.patch) _result.push(preparePatch(tSchema, connection, _ope));
162
+ else if (_ope?.put) _result.push(preparePut(tSchema, connection, _ope));
163
+ else if (_ope?.delete) _result.push(prepareDelete(tSchema, connection, _ope));
164
+ else if (_ope?.execute) _result.push(prepareExecute(connection, _ope));
165
+ else if (_ope?.begin) _result.push(prepareBegin(connection, _ope));
166
+ else if (_ope?.commit) _result.push(prepareCommit(connection, _ope));
167
+ else if (_ope?.rollback) _result.push(prepareRollback(connection, _ope));
168
+ else if (_ope?.passthrough) _result.push(preparePassthrough(connection, _ope));
155
169
  else throw new Error('Request sintax error, missing property get/patch/put/delete/...');
156
170
  });
157
171
  if (_result.length > 1) return _result;
@@ -159,17 +173,17 @@ export function prepareRun(tSchema, reqOpe) {
159
173
  return undefined;
160
174
  }
161
175
 
162
- export function prepareRunById(tSchema, idValue, reqOpe) {
163
- if (reqOpe?.get) return prepareGetById(tSchema, idValue, reqOpe);
164
- if (reqOpe?.patch) return preparePatchById(tSchema, idValue, reqOpe);
165
- if (reqOpe?.put) return preparePutById(tSchema, idValue, reqOpe);
166
- if (reqOpe?.delete) return prepareDeleteById(tSchema, idValue, reqOpe);
176
+ export function prepareRunById(tSchema, connection, reqOpe, idValue) {
177
+ if (reqOpe?.get) return prepareGetById(tSchema, connection, reqOpe, idValue);
178
+ if (reqOpe?.patch) return preparePatchById(tSchema, connection, reqOpe, idValue);
179
+ if (reqOpe?.put) return preparePutById(tSchema, connection, reqOpe, idValue);
180
+ if (reqOpe?.delete) return prepareDeleteById(tSchema, connection, reqOpe, idValue);
167
181
  else throw new Error('Request sintax error, missing property get/patch/put/delete...');
168
182
  }
169
183
 
170
- export function prepareGet(tSchema, reqOpe) {
171
- let _reqOpe = [];
172
- let _result = [];
184
+ export function prepareGet(tSchema, connection, reqOpe) {
185
+ const _reqOpe = [];
186
+ const _result = [];
173
187
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
174
188
  else _reqOpe.push(reqOpe);
175
189
  _reqOpe.forEach(function (_ope) {
@@ -184,7 +198,8 @@ export function prepareGet(tSchema, reqOpe) {
184
198
  groupsFilters: _ope?.get?.groupsFilters,
185
199
  orderBy: _ope?.get?.orderBy,
186
200
  params: _ope?.get?.params
187
- }
201
+ },
202
+ connection: connection
188
203
  });
189
204
  });
190
205
  if (_result.length > 1) return _result;
@@ -192,7 +207,7 @@ export function prepareGet(tSchema, reqOpe) {
192
207
  return undefined;
193
208
  };
194
209
 
195
- export function prepareGetById(tSchema, idValue, reqOpe) {
210
+ export function prepareGetById(tSchema, connection, reqOpe, idValue) {
196
211
  const _filters = [idField(tSchema) + ' = ' + toStringValue(idValue)];
197
212
  if (reqOpe?.get?.filters && reqOpe?.get?.filters.length > 0) {
198
213
  _filters.push('and');
@@ -204,13 +219,14 @@ export function prepareGetById(tSchema, idValue, reqOpe) {
204
219
  options: reqOpe?.get?.options,
205
220
  fields: reqOpe?.get?.fields ?? defautlFields,
206
221
  filters: _filters
207
- }
222
+ },
223
+ connection: connection
208
224
  }
209
225
  };
210
226
 
211
- export function preparePatch(tSchema, reqOpe) {
212
- let _reqOpe = [];
213
- let _result = [];
227
+ export function preparePatch(tSchema, connection, reqOpe) {
228
+ const _reqOpe = [];
229
+ const _result = [];
214
230
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
215
231
  else _reqOpe.push(reqOpe);
216
232
  _reqOpe.forEach(function (_ope) {
@@ -222,7 +238,8 @@ export function preparePatch(tSchema, reqOpe) {
222
238
  sets: _ope.patch.sets,
223
239
  filters: _ope.patch.filters,
224
240
  params: _ope?.patch.params
225
- }
241
+ },
242
+ connection: connection
226
243
  });
227
244
  }
228
245
  else throw new Error('Request sintax error, missing "patch" property.');
@@ -232,10 +249,10 @@ export function preparePatch(tSchema, reqOpe) {
232
249
  return undefined;
233
250
  };
234
251
 
235
- export function preparePatchById(tSchema, idValue, reqOpe) {
252
+ export function preparePatchById(tSchema, connection, reqOpe, idValue) {
236
253
  if (!reqOpe?.patch) throw new Error('Request sintax error, missing "patch" property.')
237
254
  if (!reqOpe.patch.sets) throw new Error('Missing "patch.sets" in operation.')
238
- let _filters = [idField(tSchema) + ' = ' + toStringValue(idValue)];
255
+ const _filters = [idField(tSchema) + ' = ' + toStringValue(idValue)];
239
256
  if (reqOpe?.patch?.filters && reqOpe?.patch?.filters.length > 0) {
240
257
  _filters.push('and');
241
258
  Array.isArray(reqOpe.patch.filters) ? _filters.push(...reqOpe.patch.filters) : _filters.push(reqOpe.patch.filters);
@@ -245,13 +262,14 @@ export function preparePatchById(tSchema, idValue, reqOpe) {
245
262
  schema: tSchema,
246
263
  sets: reqOpe.patch.sets,
247
264
  filters: _filters
248
- }
265
+ },
266
+ connection: connection
249
267
  }
250
268
  };
251
269
 
252
- export function preparePut(tSchema, reqOpe) {
253
- let _reqOpe = [];
254
- let _result = [];
270
+ export function preparePut(tSchema, connection, reqOpe) {
271
+ const _reqOpe = [];
272
+ const _result = [];
255
273
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
256
274
  else _reqOpe.push(reqOpe);
257
275
  _reqOpe.forEach(function (_ope) {
@@ -262,7 +280,8 @@ export function preparePut(tSchema, reqOpe) {
262
280
  schema: tSchema,
263
281
  sets: reqOpe.put.sets,
264
282
  params: reqOpe?.put.params
265
- }
283
+ },
284
+ connection: connection
266
285
  });
267
286
  }
268
287
  else throw new Error('Request sintax error, missing "put" property.');
@@ -272,7 +291,7 @@ export function preparePut(tSchema, reqOpe) {
272
291
  return undefined;
273
292
  };
274
293
 
275
- export function preparePutById(tSchema, idValue, reqOpe) {
294
+ export function preparePutById(tSchema, connection, reqOpe, idValue) {
276
295
  if (!reqOpe?.put) throw new Error('Request sintax error, missing "put" property.')
277
296
  if (!reqOpe.put.sets) throw new Error('Missing "put.sets" in operation.')
278
297
  reqOpe.put.sets[idField(tSchema)] = idValue;
@@ -281,13 +300,14 @@ export function preparePutById(tSchema, idValue, reqOpe) {
281
300
  schema: tSchema,
282
301
  sets: reqOpe.put.sets,
283
302
  params: reqOpe?.put?.params
284
- }
303
+ },
304
+ connection: connection
285
305
  }
286
306
  };
287
307
 
288
- export function prepareDelete(tSchema, reqOpe) {
289
- let _reqOpe = [];
290
- let _result = [];
308
+ export function prepareDelete(tSchema, connection, reqOpe) {
309
+ const _reqOpe = [];
310
+ const _result = [];
291
311
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
292
312
  else _reqOpe.push(reqOpe);
293
313
  _reqOpe.forEach(function (_ope) {
@@ -298,7 +318,8 @@ export function prepareDelete(tSchema, reqOpe) {
298
318
  schema: tSchema,
299
319
  filters: _ope.delete.filters,
300
320
  params: _ope.delete.params
301
- }
321
+ },
322
+ connection: connection
302
323
  });
303
324
  }
304
325
  else throw new Error('Request sintax error, missing "delete" property.');
@@ -308,18 +329,19 @@ export function prepareDelete(tSchema, reqOpe) {
308
329
  return undefined;
309
330
  };
310
331
 
311
- export function prepareDeleteById(tSchema, idValue) {
332
+ export function prepareDeleteById(tSchema, connection, idValue) {
312
333
  return {
313
334
  delete: {
314
335
  schema: tSchema,
315
336
  filters: [idField(tSchema) + ' = ' + toStringValue(idValue)]
316
- }
337
+ },
338
+ connection: connection
317
339
  }
318
340
  };
319
341
 
320
- export function prepareExecute(pSchema, reqOpe) {
321
- let _reqOpe = [];
322
- let _result = [];
342
+ export function prepareExecute(pSchema, connection, reqOpe) {
343
+ const _reqOpe = [];
344
+ const _result = [];
323
345
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
324
346
  else _reqOpe.push(reqOpe);
325
347
  _reqOpe.forEach(function (_ope) {
@@ -328,7 +350,8 @@ export function prepareExecute(pSchema, reqOpe) {
328
350
  schema: pSchema,
329
351
  command: pSchema.command,
330
352
  params: _ope.params
331
- }
353
+ },
354
+ connection: connection
332
355
  });
333
356
  });
334
357
  if (_result.length > 1) return _result;
@@ -336,9 +359,9 @@ export function prepareExecute(pSchema, reqOpe) {
336
359
  return undefined;
337
360
  };
338
361
 
339
- export function preparePassthrough(reqOpe) {
340
- let _reqOpe = [];
341
- let _result = [];
362
+ export function preparePassthrough(connection, reqOpe) {
363
+ const _reqOpe = [];
364
+ const _result = [];
342
365
  if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
343
366
  else _reqOpe.push(reqOpe);
344
367
  _reqOpe.forEach(function (_ope) {
@@ -348,7 +371,8 @@ export function preparePassthrough(reqOpe) {
348
371
  passthrough: {
349
372
  command: _ope.passthrough.command,
350
373
  params: _ope.passthrough.params
351
- }
374
+ },
375
+ connection: connection
352
376
  });
353
377
  }
354
378
  else throw new Error('Request sintax error, missing "passthrough" property.');
@@ -358,20 +382,23 @@ export function preparePassthrough(reqOpe) {
358
382
  return undefined;
359
383
  };
360
384
 
361
- export function prepareBegin(reqOpe) {
385
+ export function prepareBegin(connection, reqOpe) {
362
386
  return {
363
- begin: {}
387
+ begin: {},
388
+ connection: connection
364
389
  }
365
390
  };
366
391
 
367
- export function prepareCommit(reqOpe) {
392
+ export function prepareCommit(connection, reqOpe) {
368
393
  return {
369
- commit: {}
394
+ commit: {},
395
+ connection: connection
370
396
  }
371
397
  };
372
398
 
373
- export function prepareRollback(reqOpe) {
399
+ export function prepareRollback(connection, reqOpe) {
374
400
  return {
375
- rollback: {}
401
+ rollback: {},
402
+ connection: connection
376
403
  }
377
404
  };
package/lib/mssql.js CHANGED
@@ -79,11 +79,8 @@ export async function query(connection, dbOpes) {
79
79
  // Prepare sql statement
80
80
  let sqlString = '';
81
81
  let sqlRequest = pool.request();
82
- if (Array.isArray(dbOpes))
83
- dbOpes.forEach((dbOpe, index) => {
84
- if (index > 0) sqlString += '; '
85
- sqlString += ToSql(dbOpe, sqlRequest); // if exists, input params will be added to request
86
- });
82
+ // if exists, input params will be added to request
83
+ if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, sqlRequest); });
87
84
  else sqlString += ToSql(dbOpes, sqlRequest);
88
85
 
89
86
  // Run query
@@ -113,7 +110,6 @@ function ToSql(dbOpe, sqlRequest) {
113
110
  if (dbOpe.execute) return executeToSql(dbOpe, sqlRequest);
114
111
  if (dbOpe.begin) return beginToSql(dbOpe, sqlRequest);
115
112
  if (dbOpe.commit) return commitToSql(dbOpe, sqlRequest);
116
- if (dbOpe.rollback) return rollbackToSql(dbOpe, sqlRequest);
117
113
  if (dbOpe.passthrough) return passthroughToSql(dbOpe, sqlRequest);
118
114
  }
119
115
 
@@ -173,6 +169,8 @@ function getToSql(dbOpe, sqlRequest) {
173
169
 
174
170
  if (dbOpe.get.params) addParams(dbOpe.get.params, sqlRequest);
175
171
 
172
+ result += ';'
173
+
176
174
  return result;
177
175
  }
178
176
 
@@ -190,6 +188,8 @@ function patchToSql(dbOpe, sqlRequest) {
190
188
 
191
189
  if (dbOpe.patch.params) addParams(dbOpe.patch.params, sqlRequest);
192
190
 
191
+ result += ';'
192
+
193
193
  return result;
194
194
  }
195
195
 
@@ -211,6 +211,8 @@ function putToSql(dbOpe, sqlRequest) {
211
211
 
212
212
  if (dbOpe.put.params) addParams(dbOpe.put.params, sqlRequest);
213
213
 
214
+ result += ';'
215
+
214
216
  return result;
215
217
  }
216
218
 
@@ -225,6 +227,8 @@ function deleteToSql(dbOpe, sqlRequest) {
225
227
 
226
228
  if (dbOpe.delete.params) addParams(dbOpe.delete.params, sqlRequest);
227
229
 
230
+ result += ';'
231
+
228
232
  return result;
229
233
  }
230
234
 
@@ -239,22 +243,27 @@ function executeToSql(dbOpe, sqlRequest) {
239
243
 
240
244
  if (dbOpe.execute.params) addParams(dbOpe.execute.params, sqlRequest);
241
245
 
246
+ result += ';'
247
+
242
248
  return result;
243
249
  }
244
250
 
245
251
  // Parse begin operation object to sql string
246
252
  function beginToSql(dbOpe, sqlRequest) {
247
- return "BEGIN TRANSACTION";
253
+ return "BEGIN TRY BEGIN TRANSACTION;";
248
254
  }
249
255
 
250
256
  // Parse commit operation object to sql string
251
257
  function commitToSql(dbOpe, sqlRequest) {
252
- return "COMMIT";
253
- }
254
-
255
- // Parse rollback operation object to sql string
256
- function rollbackToSql(dbOpe, sqlRequest) {
257
- return "ROLLBACK";
258
+ return "IF @@TRANCOUNT > 0 COMMIT TRANSACTION; \
259
+ END TRY \
260
+ BEGIN CATCH \
261
+ IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; \
262
+ DECLARE @ErrorMessage NVARCHAR(4000); \
263
+ DECLARE @ErrorSeverity INT; \
264
+ DECLARE @ErrorState INT; \
265
+ RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState); \
266
+ END CATCH";
258
267
  }
259
268
 
260
269
  // Add input parameters to pool.request
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "db-crud-api",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "CRUD api for database tables",
6
6
  "main": "index.js",
@@ -10,8 +10,8 @@
10
10
  "author": "FF",
11
11
  "license": "MIT",
12
12
  "dependencies": {
13
- "mssql": "^9.3.2",
14
- "uuid": "^9.0.1"
13
+ "mssql": "^11.0.1",
14
+ "uuid": "^11.0.3"
15
15
  },
16
16
  "keywords":["db","crud","api"]
17
17
  }