@itrocks/mysql 0.1.3 → 0.1.5

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
@@ -1,141 +1,132 @@
1
- [![npm version](https://img.shields.io/npm/v/@itrocks/mysql?logo=npm)](https://www.npmjs.org/package/@itrocks/mysql)
2
- [![npm downloads](https://img.shields.io/npm/dm/@itrocks/mysql)](https://www.npmjs.org/package/@itrocks/mysql)
3
- [![GitHub](https://img.shields.io/github/last-commit/itrocks-ts/mysql?color=2dba4e&label=commit&logo=github)](https://github.com/itrocks-ts/mysql)
4
- [![issues](https://img.shields.io/github/issues/itrocks-ts/mysql)](https://github.com/itrocks-ts/mysql/issues)
5
- [![discord](https://img.shields.io/discord/1314141024020467782?color=7289da&label=discord&logo=discord&logoColor=white)](https://25.re/ditr)
6
-
7
1
  # mysql
8
2
 
9
3
  Transforms model objects to and from MySQL database records.
10
4
 
11
5
  ## Summary
12
6
 
13
- The `@itrocks/mysql` package provides a seamless integration with MySQL storage, supporting the common
14
- [@itrocks/storage](https://www.npmjs.com/package/@itrocks/storage) API
15
- while enabling advanced features for efficient data handling.
7
+ The `@itrocks/mysql` package provides integration with MySQL storage and implements the
8
+ standard [@itrocks/storage](https://www.npmjs.com/package/@itrocks/storage) `DataSource` API.
16
9
 
17
10
  ## Standard API
18
11
 
19
12
  The MySQL data source follows the standard [@itrocks/storage](https://www.npmjs.com/package/@itrocks/storage) API.
20
- For detailed usage, please refer to the [official documentation](https://github.com/itrocks-ts/storage)
13
+ Refer to the [storage documentation](https://github.com/itrocks-ts/storage) for generic behaviours.
21
14
 
22
15
  ## Advanced Features
23
16
 
24
- To fully utilize MySQL storage capabilities, integrate and configure the following advanced features:
17
+ To fully utilise MySQL storage capabilities, integrate and configure the following advanced dependency features:
25
18
 
26
19
  ### mysqlDependsOn
27
20
 
28
- Configure custom behaviours for MySQL data operations. Example usage (the default):
21
+ Configure custom behaviours for MySQL data operations.
22
+
29
23
  ```ts
30
24
  import { mysqlDependsOn } from '@itrocks/mysql'
31
25
 
32
26
  mysqlDependsOn({
33
- applyReadTransformer: (record, property) => record[property],
34
- applySaveTransformer: (object, property) => object[property],
35
- columnOf: name => name.toLowerCase(),
36
- componentOf: () => false,
37
- ignoreTransformedValue: Symbol('ignoreTransformedValue'),
38
- QueryFunction: class {},
39
- queryFunctionCall: () => [undefined, ' = ?'],
40
- storeOf: target => typeOf(target).name.toLowerCase()
27
+ applyReadTransformer: (record, property) => record[property],
28
+ applySaveTransformer: (object, property) => object[property],
29
+ columnOf: name => name.toLowerCase(),
30
+ componentOf: () => false,
31
+ ignoreTransformedValue: Symbol('ignoreTransformedValue'),
32
+ QueryFunction: class {},
33
+ queryFunctionCall: () => [undefined, ' = ?'],
34
+ storeOf: target => target.constructor.name.toLowerCase()
41
35
  })
42
36
  ```
43
37
 
44
38
  ### applyReadTransformer
45
39
 
46
40
  ```ts
47
- applyReadTransformer: <T extends object>(record: AnyObject, property: KeyOf<T>, object: T) => any
41
+ <T extends object>(record: AnyObject, property: KeyOf<T>, object: T) => any
48
42
  ```
49
- Transforms a property value when reading data from the database,
50
- useful for deserialization or type conversion (e.g. string to Date).
43
+
44
+ Transforms a property value when reading data from the database, e.g. for deserialization (string to Date).
51
45
 
52
46
  **Parameters:**
53
- - `record` ([AnyObject](https://github.com/itrocks-ts/class-type#anyobject)):
54
- The data record from MySQL.
55
- - `property` ([KeyOf&lt;T&gt;](https://github.com/itrocks-ts/class-type#keyof)):
56
- The property to transform.
57
- - `object` (T extends object):
58
- The object being constructed.
59
- It may be incomplete, as not all properties may have been transformed yet.
60
-
61
- **Return value:**
47
+ - `record` ([AnyObject](https://github.com/itrocks-ts/class-type#anyobject)): The data record from MySQL.
48
+ - `property` ([KeyOf&lt;T&gt;](https://github.com/itrocks-ts/class-type#keyof)): The name of the property.
49
+ - `object` (`T extends object`): The object the property value must be written to. It may be partially initialised.
50
+
51
+ **Returns:**
62
52
  - The transformed value of `property` to assign to `object`.
63
- - Alternatively, return [ignoreTransformedValue](#ignoretransformedvalue)
64
- to leave the property value unchanged in `object`.
53
+ - Returning [ignoreTransformedValue](#ignoretransformedvalue) leaves the property unchanged.
65
54
 
66
55
  ### applySaveTransformer
67
56
 
68
57
  ```ts
69
- applySaveTransformer: <T extends object>(object: T, property: KeyOf<T>, record: AnyObject) => any
58
+ <T extends object>(object: T, property: KeyOf<T>, record: AnyObject) => any
70
59
  ```
71
- Transforms a property value before saving to the database, e.g., for serialization (Date to string).
60
+
61
+ Transforms a property value before saving to the database, e.g. for serialization (Date to string).
72
62
 
73
63
  **Parameters:**
74
- - `object` (T extends object):
75
- The object being saved.
76
- - `property` ([KeyOf&lt;T&gt;](https://github.com/itrocks-ts/class-type#keyof)):
77
- The property to transform.
78
- - `record` ([AnyObject](https://github.com/itrocks-ts/class-type#anyobject)):
79
- The database record to save.
80
- It may be incomplete, as not all properties may have been transformed yet.
81
-
82
- **Return value:**
64
+ - `object` (`T extends object`): The object which property value must be transformed.
65
+ - `property` ([KeyOf&lt;T&gt;](https://github.com/itrocks-ts/class-type#keyof)): The name of the property.
66
+ - `record` ([AnyObject](https://github.com/itrocks-ts/class-type#anyobject)): The data record for MySQL writing.
67
+ It may be partially set.
68
+
69
+ **Returns:**
83
70
  - The transformed value of `property` to assign to `record`.
84
- - Alternatively, return [ignoreTransformedValue](#ignoretransformedvalue)
85
- to exclude the property and its value from `record`.
71
+ - Returning [ignoreTransformedValue](#ignoretransformedvalue) excludes the property from persistence.
72
+ - Returning an array schedules a collection save.
73
+ - Returning a function schedules a deferred operation.
74
+
75
+ **Deferred operation** (returning a function):
76
+
77
+ When `applySaveTransformer()` returns a **function**, it is not written to the SQL record.\
78
+ Instead, it is stored and executed after the object save operation completes.
79
+
80
+ The callback will receive the persisted `object` as first argument.
86
81
 
87
82
  ### columnOf
88
83
 
89
84
  ```ts
90
- columnOf: (property: string) => string
85
+ (property: string) => string
91
86
  ```
92
- Maps a property name to a database column name, enabling custom naming conventions.
87
+
88
+ Maps an object property name to a database column name.
93
89
 
94
90
  ### componentOf
95
91
 
96
92
  ```ts
97
- componentOf: <T extends object>(target: T, property: KeyOf<T>) => boolean
93
+ <T extends object>(target: T, property: KeyOf<T>) => boolean
98
94
  ```
99
- Determines whether a property represents a tightly bound component relationship (e.g., `one-to-one` or `many-to-one`).
100
- Defining this function is highly recommended to ensure proper data access from your MySQL relational database.
101
95
 
102
- By default, properties are assumed to represent related collections
103
- (e.g., `many-to-many` or `one-to-many` relationships).
96
+ Indicates whether a collection property is stored as components (one-to-many / owned) instead of a link table.
104
97
 
105
98
  ### ignoreTransformedValue
106
99
 
107
- ```ts
108
- ignoreTransformedValue: any
109
- ```
110
- This marker value is used to skip property transformation during read or save operations.
111
- It is returned by your implementation of [applyReadTransformer](#applyreadtransformer)
112
- and [applySaveTransformer](#applysavetransformer), as needed.
100
+ Marker value used by transformers to prevent persistence or assignment after the callback is executed.
113
101
 
114
102
  ### QueryFunction
115
103
 
116
104
  ```ts
117
- QueryFunction: Type<QF>
105
+ Type<QF>
118
106
  ```
119
- Specificies a custom query function type for advanced search operations.
107
+
108
+ Base class for custom query functions.
120
109
 
121
110
  ### queryFunctionCall
122
111
 
123
112
  ```ts
124
- queryFunctionCall: (value: QF) => [value: any, sql: string]
113
+ (value: QF) => [any, string]
125
114
  ```
126
- Processes custom query functions, returning the SQL fragment and associated values.
115
+
116
+ Converts a query function into a SQL fragment and its bound value.
127
117
 
128
118
  **Parameters:**
129
119
  - `value`: An object of a class derived from the one defined by [QueryFunction](#queryfunction).
130
120
 
131
121
  **Returns:**
132
- - `value`: The value associated with the query function
133
- - `sql`: The corresponding SQL fragment
122
+ - `any`: The value associated with the query function
123
+ - `string`: The corresponding SQL fragment
134
124
 
135
125
  ### storeOf
136
126
 
137
127
  ```ts
138
- storeOf: <T extends object>(target: ObjectOrType<T>) => string | false
128
+ <T extends object>(target: ObjectOrType<T>) => string | false
139
129
  ```
140
- Maps a class ([ObjectOrType](https://github.com/itrocks-ts/class-type#objectortype))
141
- to its corresponding database table name, allowing for custom naming conventions.
130
+
131
+ Maps a [class or object](https://github.com/itrocks-ts/class-type#objectortype) to its table name.
132
+ Returning `false` disables persistence for that type.
package/cjs/mysql.js CHANGED
@@ -56,9 +56,10 @@ class Mysql extends storage_1.DataSource {
56
56
  }
57
57
  async count(type, search = {}) {
58
58
  const connection = this.connection ?? await this.connect();
59
- Object.setPrototypeOf(search, type.prototype);
60
- const sql = this.propertiesToSearchSql(search);
61
- const [values] = await this.valuesToDb(search);
59
+ const localSearch = { ...search };
60
+ Object.setPrototypeOf(localSearch, type.prototype);
61
+ const sql = this.propertiesToSearchSql(localSearch);
62
+ const [values] = await this.valuesToDb(localSearch);
62
63
  if (exports.DEBUG)
63
64
  console.log('SELECT COUNT(*) FROM `' + depends.storeOf(type) + '`' + sql, JSON.stringify(values));
64
65
  const row = (await connection.query('SELECT COUNT(*) `count` FROM `' + depends.storeOf(type) + '`' + sql, Object.values(values)))[0];
@@ -99,7 +100,7 @@ class Mysql extends storage_1.DataSource {
99
100
  const id = result.insertId;
100
101
  const entity = this.connectObject(object, ((id >= Number.MIN_SAFE_INTEGER) && (id <= Number.MAX_SAFE_INTEGER)) ? Number(id) : id);
101
102
  for (const callback of deferred) {
102
- callback(object);
103
+ await callback(object);
103
104
  }
104
105
  return entity;
105
106
  }
@@ -334,9 +335,10 @@ class Mysql extends storage_1.DataSource {
334
335
  sortOption = option.properties.length ? option : new storage_3.Sort((0, sort_2.sortOf)(type));
335
336
  }
336
337
  }
337
- Object.setPrototypeOf(search, type.prototype);
338
- const sql = this.propertiesToSearchSql(search);
339
- const [values] = await this.valuesToDb(search);
338
+ const localSearch = { ...search };
339
+ Object.setPrototypeOf(localSearch, type.prototype);
340
+ const sql = this.propertiesToSearchSql(localSearch);
341
+ const [values] = await this.valuesToDb(localSearch);
340
342
  if (exports.DEBUG)
341
343
  console.log('SELECT ' + propertiesSql + ' FROM `' + depends.storeOf(type) + '`' + sql, JSON.stringify(values));
342
344
  const limit = limitOption?.limit ? ' LIMIT ' + limitOption.limit : '';
@@ -359,7 +361,7 @@ class Mysql extends storage_1.DataSource {
359
361
  console.log(query, JSON.stringify(Object.values(values).concat([object.id])));
360
362
  await connection.query(query, Object.values(values).concat([object.id]));
361
363
  for (const callback of deferred) {
362
- callback(object);
364
+ await callback(object);
363
365
  }
364
366
  return object;
365
367
  }
package/esm/mysql.js CHANGED
@@ -51,9 +51,10 @@ export class Mysql extends DataSource {
51
51
  }
52
52
  async count(type, search = {}) {
53
53
  const connection = this.connection ?? await this.connect();
54
- Object.setPrototypeOf(search, type.prototype);
55
- const sql = this.propertiesToSearchSql(search);
56
- const [values] = await this.valuesToDb(search);
54
+ const localSearch = { ...search };
55
+ Object.setPrototypeOf(localSearch, type.prototype);
56
+ const sql = this.propertiesToSearchSql(localSearch);
57
+ const [values] = await this.valuesToDb(localSearch);
57
58
  if (DEBUG)
58
59
  console.log('SELECT COUNT(*) FROM `' + depends.storeOf(type) + '`' + sql, JSON.stringify(values));
59
60
  const row = (await connection.query('SELECT COUNT(*) `count` FROM `' + depends.storeOf(type) + '`' + sql, Object.values(values)))[0];
@@ -94,7 +95,7 @@ export class Mysql extends DataSource {
94
95
  const id = result.insertId;
95
96
  const entity = this.connectObject(object, ((id >= Number.MIN_SAFE_INTEGER) && (id <= Number.MAX_SAFE_INTEGER)) ? Number(id) : id);
96
97
  for (const callback of deferred) {
97
- callback(object);
98
+ await callback(object);
98
99
  }
99
100
  return entity;
100
101
  }
@@ -329,9 +330,10 @@ export class Mysql extends DataSource {
329
330
  sortOption = option.properties.length ? option : new Sort(sortOf(type));
330
331
  }
331
332
  }
332
- Object.setPrototypeOf(search, type.prototype);
333
- const sql = this.propertiesToSearchSql(search);
334
- const [values] = await this.valuesToDb(search);
333
+ const localSearch = { ...search };
334
+ Object.setPrototypeOf(localSearch, type.prototype);
335
+ const sql = this.propertiesToSearchSql(localSearch);
336
+ const [values] = await this.valuesToDb(localSearch);
335
337
  if (DEBUG)
336
338
  console.log('SELECT ' + propertiesSql + ' FROM `' + depends.storeOf(type) + '`' + sql, JSON.stringify(values));
337
339
  const limit = limitOption?.limit ? ' LIMIT ' + limitOption.limit : '';
@@ -354,7 +356,7 @@ export class Mysql extends DataSource {
354
356
  console.log(query, JSON.stringify(Object.values(values).concat([object.id])));
355
357
  await connection.query(query, Object.values(values).concat([object.id]));
356
358
  for (const callback of deferred) {
357
- callback(object);
359
+ await callback(object);
358
360
  }
359
361
  return object;
360
362
  }
package/package.json CHANGED
@@ -5,6 +5,8 @@
5
5
  },
6
6
  "dependencies": {
7
7
  "@itrocks/class-type": "latest",
8
+ "@itrocks/composition": "latest",
9
+ "@itrocks/property-type": "latest",
8
10
  "@itrocks/reflect": "latest",
9
11
  "@itrocks/sort": "latest",
10
12
  "@itrocks/storage": "latest",
@@ -59,5 +61,5 @@
59
61
  "build:esm": "tsc -p tsconfig.esm.json"
60
62
  },
61
63
  "types": "./esm/mysql.d.ts",
62
- "version": "0.1.3"
64
+ "version": "0.1.5"
63
65
  }