ztechno_core 0.0.77 → 0.0.81

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.
@@ -1,6 +1,10 @@
1
1
  import * as mysql from 'mysql';
2
2
  type ZOnErrorCallback = (err: mysql.MysqlError) => any;
3
3
  type ZOnLogCallback = (log: string) => any;
4
+ export type ZSQLOptions = mysql.PoolConfig & {
5
+ dateStringTimezone?: string;
6
+ parseBooleans?: boolean;
7
+ };
4
8
  export declare class ZSQLService {
5
9
  private options;
6
10
  private pool;
@@ -8,15 +12,31 @@ export declare class ZSQLService {
8
12
  private listeners;
9
13
  private databaseName;
10
14
  get database(): string;
11
- constructor(
12
- options: mysql.PoolConfig & {
13
- dateStringTimezone?: string;
14
- },
15
- );
15
+ /**
16
+ * Creates a new ZSQLService instance with a MySQL connection pool.
17
+ * @param options - MySQL pool configuration options including custom dateStringTimezone and parseBooleans settings
18
+ */
19
+ constructor(options: ZSQLOptions);
20
+ /**
21
+ * Registers an event listener for database errors or logs.
22
+ * @param eventName - The event type to listen for ('err' or 'log')
23
+ * @param listener - The callback function to execute when the event occurs
24
+ * @throws Error if the event name is not supported
25
+ */
16
26
  on(eventName: 'err', listener: ZOnErrorCallback): void;
17
27
  on(eventName: 'log', listener: ZOnLogCallback): void;
18
28
  private triggerEvent;
19
29
  private getPoolConnection;
30
+ /**
31
+ * Executes a SQL query with automatic type conversion for dates and booleans.
32
+ * Converts TINYINT(1) columns to booleans if parseBooleans option is enabled.
33
+ * Converts date strings to Date objects if dateStringTimezone option is set.
34
+ * @template T - The expected result type
35
+ * @param opt - Query options containing the SQL query string and optional parameters
36
+ * @param opt.query - The SQL query string to execute
37
+ * @param opt.params - Optional query parameters (array for positional, object for named parameters)
38
+ * @returns Promise resolving to query results with type conversions applied
39
+ */
20
40
  exec(opt: {
21
41
  query: string;
22
42
  params?:
@@ -36,12 +56,29 @@ export declare class ZSQLService {
36
56
  [key: string]: any;
37
57
  };
38
58
  }): Promise<T>;
59
+ /**
60
+ * Legacy method to execute a SQL query. Uses uppercase property names for backwards compatibility.
61
+ * Does not apply date or boolean conversions. Consider using exec() instead.
62
+ * @template T - The expected result type
63
+ * @param opt - Query options
64
+ * @param opt.Query - The SQL query string to execute
65
+ * @param opt.Params - Named parameters for the query
66
+ * @returns Promise resolving to query results
67
+ */
39
68
  fetch<T = any>(opt: {
40
69
  Query: string;
41
70
  Params: {
42
71
  [key: string]: any;
43
72
  };
44
73
  }): Promise<T[]>;
74
+ /**
75
+ * Executes a SQL query without type conversions.
76
+ * Supports both positional (array) and named (object) parameters.
77
+ * @template T - The expected result type
78
+ * @param sql - The SQL query string to execute
79
+ * @param params - Optional query parameters (array for positional with ?, object for named with :key)
80
+ * @returns Promise resolving to query results or insert/update metadata
81
+ */
45
82
  query(
46
83
  sql: string,
47
84
  params?:
@@ -61,7 +98,16 @@ export declare class ZSQLService {
61
98
  [key: string]: any;
62
99
  },
63
100
  ): Promise<T[]>;
101
+ private queryWithFields;
64
102
  private formatQueryParams;
65
103
  private isSqlDate;
104
+ /**
105
+ * Changes the active database by closing the current connection pool and creating a new one.
106
+ * All active connections will be gracefully closed before switching.
107
+ * @param newDatabase - The name of the database to switch to
108
+ * @returns Promise that resolves when the database has been changed successfully
109
+ * @throws Error if the pool cannot be closed or new pool cannot be created
110
+ */
111
+ changeDatabase(newDatabase: string): Promise<void>;
66
112
  }
67
113
  export {};
@@ -46,6 +46,10 @@ class ZSQLService {
46
46
  get database() {
47
47
  return this.databaseName;
48
48
  }
49
+ /**
50
+ * Creates a new ZSQLService instance with a MySQL connection pool.
51
+ * @param options - MySQL pool configuration options including custom dateStringTimezone and parseBooleans settings
52
+ */
49
53
  constructor(options) {
50
54
  this.options = options;
51
55
  this.defaultPoolconfig = {
@@ -84,22 +88,44 @@ class ZSQLService {
84
88
  });
85
89
  }
86
90
  async exec(opt) {
87
- const rows = await this.query(opt.query, opt.params);
88
- if (!Array.isArray(rows)) {
89
- return rows;
91
+ const { results, fields } = await this.queryWithFields(opt.query, opt.params);
92
+ if (!Array.isArray(results)) {
93
+ return results;
90
94
  }
91
- if (!this.options.dateStringTimezone) {
92
- return rows;
95
+ if (!this.options.dateStringTimezone && !this.options.parseBooleans) {
96
+ return results;
93
97
  }
94
- return rows.map((row) => {
98
+ // Build a set of column names that are TINYINT(1) for boolean conversion
99
+ const booleanColumns = new Set();
100
+ if (this.options.parseBooleans && fields) {
101
+ fields.forEach((field) => {
102
+ // Check if column is TINYINT(1) - type 1 is TINY, length 1 means TINYINT(1)
103
+ if (field.type === 1 && field.length === 1) {
104
+ booleanColumns.add(field.name);
105
+ }
106
+ });
107
+ }
108
+ return results.map((row) => {
95
109
  Object.keys(row).map((key) => {
96
- if (this.isSqlDate(row[key])) {
110
+ if (this.options.dateStringTimezone && this.isSqlDate(row[key])) {
97
111
  row[key] = new Date(row[key] + this.options.dateStringTimezone);
98
112
  }
113
+ if (this.options.parseBooleans && booleanColumns.has(key) && (row[key] === 0 || row[key] === 1)) {
114
+ row[key] = row[key] === 1;
115
+ }
99
116
  });
100
117
  return row;
101
118
  });
102
119
  }
120
+ /**
121
+ * Legacy method to execute a SQL query. Uses uppercase property names for backwards compatibility.
122
+ * Does not apply date or boolean conversions. Consider using exec() instead.
123
+ * @template T - The expected result type
124
+ * @param opt - Query options
125
+ * @param opt.Query - The SQL query string to execute
126
+ * @param opt.Params - Named parameters for the query
127
+ * @returns Promise resolving to query results
128
+ */
103
129
  async fetch(opt) {
104
130
  const items = await this.query(opt.Query, opt.Params);
105
131
  return items;
@@ -126,6 +152,40 @@ class ZSQLService {
126
152
  throw err;
127
153
  }
128
154
  }
155
+ async queryWithFields(sql, params) {
156
+ try {
157
+ const con = await this.getPoolConnection();
158
+ try {
159
+ const output = await new Promise((resolve, reject) => {
160
+ if (Array.isArray(params)) {
161
+ con.query(sql, params, (err, results, fields) => {
162
+ if (err) {
163
+ reject(err);
164
+ } else {
165
+ resolve({ results, fields });
166
+ }
167
+ });
168
+ } else {
169
+ sql = this.formatQueryParams(con, sql, params);
170
+ con.query(sql, (err, results, fields) => {
171
+ if (err) {
172
+ reject(err);
173
+ } else {
174
+ resolve({ results, fields });
175
+ }
176
+ });
177
+ }
178
+ });
179
+ con.release();
180
+ return output;
181
+ } catch (err) {
182
+ con.release();
183
+ throw err;
184
+ }
185
+ } catch (err) {
186
+ throw err;
187
+ }
188
+ }
129
189
  formatQueryParams(con, query, values) {
130
190
  if (!values) {
131
191
  return query;
@@ -148,5 +208,34 @@ class ZSQLService {
148
208
  }
149
209
  return false;
150
210
  }
211
+ /**
212
+ * Changes the active database by closing the current connection pool and creating a new one.
213
+ * All active connections will be gracefully closed before switching.
214
+ * @param newDatabase - The name of the database to switch to
215
+ * @returns Promise that resolves when the database has been changed successfully
216
+ * @throws Error if the pool cannot be closed or new pool cannot be created
217
+ */
218
+ async changeDatabase(newDatabase) {
219
+ return new Promise((resolve, reject) => {
220
+ this.pool.end((err) => {
221
+ if (err) {
222
+ reject(err);
223
+ return;
224
+ }
225
+ this.databaseName = newDatabase;
226
+ const newOptions = { ...this.options, database: newDatabase };
227
+ this.pool = mysql.createPool(Object.assign({}, this.defaultPoolconfig, newOptions));
228
+ this.pool.on('connection', (connection) => {
229
+ connection.on('error', (err) => {
230
+ this.triggerEvent('err', err);
231
+ });
232
+ connection.on('close', (err) => {
233
+ this.triggerEvent('err', err);
234
+ });
235
+ });
236
+ resolve();
237
+ });
238
+ });
239
+ }
151
240
  }
152
241
  exports.ZSQLService = ZSQLService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ztechno_core",
3
- "version": "0.0.77",
3
+ "version": "0.0.81",
4
4
  "description": "Core files for ztechno framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",