@itrocks/mysql-maintainer 0.2.5 → 0.2.7

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
@@ -8,267 +8,87 @@
8
8
 
9
9
  Reactively maintains database structure by updating schema and retrying on MySQL errors.
10
10
 
11
- *This documentation was written by an artificial intelligence and may contain errors or approximations.
12
- It has not yet been fully reviewed by a human. If anything seems unclear or incomplete,
13
- please feel free to contact the author of this package.*
11
+ Connect this package to [`@itrocks/mysql`](https://github.com/itrocks-ts/mysql), then keep using your MySQL data
12
+ sources normally. Their database structure is maintained automatically, as operations need it, when persistent object
13
+ structures evolve. There are no migration files to write and no maintenance API to call.
14
14
 
15
- ## Installation
15
+ ## Use with the it.rocks framework
16
16
 
17
- ```bash
18
- npm i @itrocks/mysql-maintainer
19
- ```
20
-
21
- ## Usage
22
-
23
- `@itrocks/mysql-maintainer` provides two main entry points:
24
-
25
- - the `Mysql` class, a drop‑in replacement for `@itrocks/mysql` that
26
- automatically keeps your MySQL/MariaDB schema in sync with your
27
- TypeScript models while you work with data;
28
- - the `MysqlMaintainer` class, a lower‑level helper you can call
29
- directly when you want to create or update tables yourself.
30
-
31
- In both cases, the package reacts to common MySQL errors
32
- (`ER_BAD_FIELD_ERROR`, `ER_CANNOT_ADD_FOREIGN`, `ER_NO_SUCH_TABLE`) and
33
- updates the database structure, then transparently retries the failed
34
- query.
35
-
36
- ### Minimal example: automatic schema maintenance
37
-
38
- ```ts
39
- import { Mysql } from '@itrocks/mysql-maintainer'
40
- import { Entity } from '@itrocks/storage'
41
-
42
- class User extends Entity<User>
43
- {
44
- name = ''
45
- email = ''
46
- }
47
-
48
- async function main() {
49
- const mysql = new Mysql({
50
- // Same connection options as @itrocks/mysql / mariadb
51
- host: 'localhost',
52
- user: 'root',
53
- database: 'demo',
54
- })
55
-
56
- // On first call, mysql-maintainer will create or update the
57
- // corresponding table based on the User class definition, then retry
58
- // the insert.
59
- await mysql.insert(new User().assign({ name: 'Alice', email: 'a@example.com' }))
60
- }
61
- ```
62
-
63
- You can continue using the `Mysql` instance as you would use
64
- `@itrocks/mysql`: methods such as `read`, `search`, `update`, and
65
- collection helpers are forwarded to the base implementation, while
66
- `mysql-maintainer` keeps track of the involved entities and adjusts the
67
- schema when needed.
68
-
69
- ### Example: maintaining join tables on collection access
70
-
71
- When you read many‑to‑many relationships defined as collections on your
72
- entities, `Mysql` automatically creates or updates the implicit join
73
- table.
17
+ An application based on [`@itrocks/framework`](https://github.com/itrocks-ts/framework) needs the framework, the MySQL
18
+ data source, and this package:
74
19
 
75
- ```ts
76
- import { Mysql } from '@itrocks/mysql-maintainer'
77
- import { Entity } from '@itrocks/storage'
78
-
79
- class Tag extends Entity<Tag>
80
- {
81
- name = ''
82
- }
83
-
84
- class Article extends Entity<Article>
85
- {
86
- title = ''
87
-
88
- // Many-to-many with Tag; the framework will map this to a join table
89
- tags: Tag[] = []
90
- }
91
-
92
- async function loadArticleTags(id: number) {
93
- const mysql = new Mysql({ database: 'demo' })
94
-
95
- const article = await mysql.read(Article, id)
96
-
97
- // If the join table does not exist yet or is out of date, it will be
98
- // created/updated before the query is retried.
99
- const tags = await mysql.readCollection(article, 'tags')
100
- return tags
101
- }
102
- ```
103
-
104
- ### Example: using MysqlMaintainer directly
105
-
106
- If you want to control when schema updates happen (for instance during a
107
- deployment step or a migration command), you can work with
108
- `MysqlMaintainer` and a `mariadb` connection.
109
-
110
- ```ts
111
- import { createConnection } from 'mariadb'
112
- import { MysqlMaintainer } from '@itrocks/mysql-maintainer'
113
- import { Entity } from '@itrocks/storage'
114
-
115
- class Product extends Entity<Product>
116
- {
117
- name = ''
118
- price = 0
119
- }
120
-
121
- async function ensureSchema() {
122
- const connection = await createConnection({ database: 'demo' })
123
- const schemaManager = new MysqlMaintainer(connection)
124
-
125
- // Create or update the table corresponding to Product
126
- await schemaManager.updateTable(Product)
127
-
128
- await connection.end()
129
- }
20
+ ```bash
21
+ npm i @itrocks/framework @itrocks/mysql @itrocks/mysql-maintainer
130
22
  ```
131
23
 
132
- ## API
24
+ Add the composition and the main MySQL data source to the project's `config.yaml`:
133
25
 
134
- ### `class Mysql extends @itrocks/mysql.Mysql`
26
+ ```yaml
27
+ compose:
28
+ '@itrocks/mysql:Mysql': '@itrocks/mysql-maintainer:Mysql'
135
29
 
136
- Enhanced MySQL storage class that automatically tracks the context of
137
- operations and lets `MysqlMaintainer` react to schema‑related errors.
138
-
139
- Aside from the behavior described below, it exposes the same public API
140
- as `@itrocks/mysql.Mysql`.
141
-
142
- #### Properties
143
-
144
- - `connection?: ContextualConnection` – the underlying `mariadb`
145
- connection wrapped with additional context information. You normally
146
- do not interact with it directly.
147
-
148
- #### Methods
149
-
150
- All methods have the same signature and return types as in
151
- `@itrocks/mysql.Mysql`; the extra behavior is that each call pushes the
152
- relevant entity type or instance to an internal context stack before the
153
- query, and pops it afterwards.
154
-
155
- - `async connect(): Promise<ContextualConnection>`
156
-
157
- Opens the connection and installs the contextual behavior so that
158
- errors can trigger schema maintenance.
159
-
160
- - `async insert<T extends object>(object: T): Promise<Entity<T>>`
161
-
162
- Inserts a new row for `object`. If a “table does not exist” or
163
- “column not found / foreign key failed” error occurs, the
164
- corresponding table (and, for collections, the join table) is created
165
- or updated and the query is retried.
166
-
167
- - `async update<T extends object>(object: Entity<T>): Promise<Entity<T>>`
168
-
169
- Updates an existing row; schema maintenance/automatic retry applies in
170
- the same way as for `insert`.
171
-
172
- - `async deleteId<T extends object>(type: ObjectOrType<T>, id: any, property?: KeyOf<Entity<T>>): Promise<void>`
173
-
174
- Deletes a row by its identifier; the entity `type` is used as context
175
- for potential schema updates.
176
-
177
- - `async deleteRelatedId<T extends Entity>(object: T, property: KeyOf<T>, id: Identifier): Promise<void>`
178
-
179
- Deletes a related entity (for example from a collection association).
180
-
181
- - `async read<T extends object>(type: Type<T>, id: Identifier): Promise<Entity<T> | undefined>`
182
-
183
- Reads a single entity instance by identifier.
184
-
185
- - `async readMultiple<T extends object>(type: Type<T>, ids: Identifier[]): Promise<Entity<T>[]>`
186
-
187
- Reads several entities by their identifiers.
188
-
189
- - `async readCollection<T extends object, PT extends object>(object: Entity<T>, property: KeyOf<T>, type?: Type<PT>): Promise<Entity<PT>[]>`
190
-
191
- Reads a collection relationship (for example `article.tags`). The
192
- context includes both the owning object and the related type so that
193
- the implicit join table can be created or updated if necessary.
194
-
195
- - `async readCollectionIds<T extends object, PT extends object>(object: Entity<T>, property: KeyOf<T>, type?: Type<PT>): Promise<Identifier[]>`
196
-
197
- Same as `readCollection`, but only retrieves identifiers.
198
-
199
- - `async search<T extends object>(type: Type<T>, search?: SearchType<T>, options?: Options): Promise<Entity<T>[]>`
200
-
201
- Searches entities; the entity `type` becomes the context for schema
202
- maintenance.
203
-
204
- ### `class MysqlMaintainer`
205
-
206
- Low‑level utility that knows how to translate your TypeScript entity
207
- definitions (via reflection and schema packages) into MySQL tables and
208
- how to react to common schema‑related errors.
209
-
210
- #### Constructor
211
-
212
- ```ts
213
- const maintainer = new MysqlMaintainer(connection)
30
+ dataSource:
31
+ engine: '@itrocks/mysql'
32
+ host: localhost
33
+ user: application
34
+ password: secret
35
+ database: application
214
36
  ```
215
37
 
216
- - `connection` – a `mariadb` `Connection` used to inspect and modify the
217
- database schema.
218
-
219
- #### Methods
38
+ The `compose` entry enriches `@itrocks/mysql` with the automatic maintenance behaviour. It uses the standard
39
+ [`@itrocks/compose`](https://github.com/itrocks-ts/compose) mechanism for enriching one module with another module's
40
+ features.
220
41
 
221
- - `async createImplicitTable(type1: ObjectOrType, type2: ObjectOrType): Promise<boolean>`
42
+ The `dataSource` entry above configures the project's main data source. You can instead create other MySQL data sources
43
+ as described in the [`@itrocks/mysql` documentation](https://github.com/itrocks-ts/mysql). Every data source based on
44
+ the composed `@itrocks/mysql` implementation is maintained automatically.
222
45
 
223
- Creates a join table between the two entity types, with a composite
224
- primary key and cascading foreign keys. Returns `true` once the table
225
- has been created.
46
+ That is the complete setup. Keep changing and using persistent object classes through the usual it.rocks storage
47
+ operations; the required database changes are applied when an operation first needs them.
226
48
 
227
- - `async createTable(type: Type): Promise<boolean>`
49
+ ## Use outside the it.rocks framework
228
50
 
229
- Creates a table corresponding to the given entity `type`. Throws if no
230
- table name can be resolved for the type.
51
+ The same integration principle can be used without `@itrocks/framework`:
231
52
 
232
- - `implicitTableName(type1: ObjectOrType, type2: ObjectOrType): string`
53
+ 1. Install [`@itrocks/mysql`](https://github.com/itrocks-ts/mysql) and a mixin-based composition system such as
54
+ [`@itrocks/compose`](https://github.com/itrocks-ts/compose). A wrapper implementing the same API as `@itrocks/mysql`
55
+ can be used instead.
56
+ 2. Create the required `@itrocks/mysql` data sources as described in its
57
+ [documentation](https://github.com/itrocks-ts/mysql). This package does not change how data sources are configured.
58
+ 3. Install `@itrocks/mysql-maintainer` in the project.
59
+ 4. Use the chosen composition system to enrich the `Mysql` implementation from `@itrocks/mysql` with the behaviour
60
+ supplied by `@itrocks/mysql-maintainer`. Refer to the
61
+ [`@itrocks/compose` documentation](https://github.com/itrocks-ts/compose) when using that package.
62
+ 5. Use the MySQL data sources normally. Their operations now trigger automatic maintenance when the current database
63
+ structure no longer supports the persistent object model.
233
64
 
234
- Returns the name of the join table that would be used for a
235
- many‑to‑many association between `type1` and `type2`. Throws if one of
236
- the types is not mapped to a table.
65
+ The application integrator is responsible for performing the composition early enough and according to the chosen
66
+ composition system's loading rules.
237
67
 
238
- - `async manageError(error: SqlError, context: Context, sql: string | QueryOptions, values: any[]): Promise<boolean>`
68
+ ## How it works
239
69
 
240
- Examines the MySQL error and, when it corresponds to a managed error
241
- code, updates the tables for the provided `context` (entity type,
242
- instance, or pair `[owner, relatedType]`). Returns `true` if the error
243
- has been handled and the caller should retry the query, `false`
244
- otherwise.
70
+ The package enriches the usual `Mysql` operations with the context required to identify the persistent classes involved.
71
+ It intercepts MySQL errors that indicate a missing or outdated table, column, or foreign key, derives the expected
72
+ schema from the object model, applies the required structural changes, and retries the original operation.
245
73
 
246
- - `async updateContextTables(context: Context, tableName?: string): Promise<boolean>`
74
+ For example, a read follows this simplified sequence:
247
75
 
248
- Internal helper that inspects the database to see whether the table
249
- for each context entity already exists. If not, it calls
250
- `createTable`; otherwise it calls `updateTable`. When two contexts are
251
- provided and their implicit join table matches `tableName`, the join
252
- table is also created.
76
+ 1. The application reads an object through a MySQL data source as usual.
77
+ 2. The enriched data source records the class being read and executes the SQL query.
78
+ 3. If MySQL reports a supported structure error, the maintainer compares the database with the schema derived from
79
+ that class and updates the affected table or relationship table.
80
+ 4. The data source retries the same query and returns the read result to the application.
253
81
 
254
- - `async updateTable(type: Type): Promise<boolean>`
82
+ The exported classes that implement context tracking, error handling, schema updates, and retries are internal
83
+ mechanics of this integration. They are not a separate API that an application needs to call.
255
84
 
256
- Computes the difference between the current MySQL table and the table
257
- that should exist according to the entity `type`, then applies the
258
- required SQL changes. Returns `true` when a change has been applied,
259
- `false` when the schema was already up to date.
85
+ ## Persistent model requirements
260
86
 
261
- ## Typical use cases
87
+ Automatic maintenance derives database structure from business classes and their reflection metadata. Those classes
88
+ must follow the it.rocks persistent object conventions, including the decorators and metadata used by its ORM packages.
262
89
 
263
- - Rapid prototyping: evolve your TypeScript entity models and let
264
- `mysql-maintainer` adjust the database schema on the fly while you
265
- insert, update, or query data.
266
- - Developer workstations and test environments where automatic schema
267
- updates remove the need for manual migrations.
268
- - Applications with many small deployments where you prefer incremental
269
- schema evolution handled by the application itself.
270
- - Projects using the `@itrocks/storage` / `@itrocks/mysql` stack that
271
- want schema maintenance without writing migration scripts.
272
- - Custom migration tools or CLI scripts built on top of
273
- `MysqlMaintainer` to validate and update schema before a new version
274
- of the application is started.
90
+ The current implementation is strongly coupled to the it.rocks ORM ecosystem. Its
91
+ [`npm dependencies`](https://www.npmjs.com/package/@itrocks/mysql-maintainer?activeTab=dependencies) show the
92
+ reflection, storage, schema conversion, and schema diff modules involved. Outside a full it.rocks application, the
93
+ integrator must provide a compatible model and metadata environment in addition to the MySQL and composition
94
+ integrations described above.
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "description": "Reactively maintains database structure by updating schema and retrying on MySQL errors",
19
19
  "devDependencies": {
20
- "typescript": "^6.0"
20
+ "typescript": "^7.0"
21
21
  },
22
22
  "engines": {
23
23
  "node": ">=24"
@@ -51,5 +51,5 @@
51
51
  "scripts": {
52
52
  "build": "tsc"
53
53
  },
54
- "version": "0.2.5"
54
+ "version": "0.2.7"
55
55
  }
@@ -1,16 +0,0 @@
1
- import { ObjectOrType } from '@itrocks/class-type';
2
- import { Connection } from 'mariadb';
3
- import { QueryOptions } from 'mariadb-share';
4
- import { SqlError } from 'mariadb-share';
5
- export type Context = ObjectOrType | ObjectOrType[];
6
- export declare class Contextual implements Partial<Connection> {
7
- [x: number]: (() => Promise<void>) | undefined;
8
- contexts: Context[];
9
- errorCount: Record<string, Record<string, Array<number>>>;
10
- superQuery: <T = any>(sql: string | QueryOptions, values?: any) => Promise<T>;
11
- applyTo(connection: ContextualConnection): Promise<ContextualConnection>;
12
- incrementErrorCount(sql: string, error: any): this is Connection;
13
- isSqlError(error: any): error is SqlError;
14
- query<T = any>(sql: string | QueryOptions, values?: any): Promise<T>;
15
- }
16
- export type ContextualConnection = Connection & Contextual;
@@ -1,59 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Contextual = void 0;
4
- const mysql_maintainer_1 = require("./mysql-maintainer");
5
- const mysql_maintainer_2 = require("./mysql-maintainer");
6
- const MANAGED_ERROR_CODES = ['ER_BAD_FIELD_ERROR', 'ER_CANNOT_ADD_FOREIGN', 'ER_NO_SUCH_TABLE'];
7
- class Contextual {
8
- contexts = [];
9
- errorCount = {};
10
- superQuery = () => new Promise(() => { });
11
- async applyTo(connection) {
12
- connection.contexts = [];
13
- connection.errorCount = {};
14
- connection.incrementErrorCount = Contextual.prototype.incrementErrorCount;
15
- connection.isSqlError = Contextual.prototype.isSqlError;
16
- connection.superQuery = connection.query;
17
- connection.query = Contextual.prototype.query;
18
- return connection;
19
- }
20
- incrementErrorCount(sql, error) {
21
- if (!this.errorCount[sql]) {
22
- this.errorCount[sql] = {};
23
- }
24
- if (!this.errorCount[sql][error.message]) {
25
- this.errorCount[sql][error.message] = [];
26
- }
27
- this.errorCount[sql][error.message].push(new Date().getTime());
28
- console.log('incremented', this.errorCount[sql][error.message].length, ':', sql, error.message);
29
- return true;
30
- }
31
- isSqlError(error) {
32
- return (typeof error === 'object') && !!error.code;
33
- }
34
- async query(sql, values) {
35
- try {
36
- if (mysql_maintainer_1.DEBUG)
37
- console.log(sql, values);
38
- return await this.superQuery(sql, values);
39
- }
40
- catch (error) {
41
- if (!this.isSqlError(error) || !MANAGED_ERROR_CODES.includes(error.code)) {
42
- if (mysql_maintainer_1.DEBUG)
43
- console.log('MAINTAINER: throw', error);
44
- throw error;
45
- }
46
- sql = (typeof sql === 'object') ? sql.sql : sql;
47
- if (this.incrementErrorCount(sql, error)
48
- && (this.errorCount[sql][error.message].length < 5)
49
- && await new mysql_maintainer_2.MysqlMaintainer(this).manageError(error, this.contexts[this.contexts.length - 1], sql, values)) {
50
- return this.query(sql, values);
51
- }
52
- if (mysql_maintainer_1.DEBUG)
53
- console.log('MAINTAINER: throw (2)', error);
54
- throw error;
55
- }
56
- }
57
- }
58
- exports.Contextual = Contextual;
59
- //# sourceMappingURL=contextual-connection.js.map
@@ -1,18 +0,0 @@
1
- import { ObjectOrType } from '@itrocks/class-type';
2
- import { Type } from '@itrocks/class-type';
3
- import { Connection } from 'mariadb';
4
- import { QueryOptions } from 'mariadb-share';
5
- import { SqlError } from 'mariadb-share';
6
- import { Context } from './contextual-connection';
7
- export { Mysql } from './mysql';
8
- export declare const DEBUG = false;
9
- export declare class MysqlMaintainer {
10
- connection: Connection;
11
- constructor(connection: Connection);
12
- createImplicitTable(type1: ObjectOrType, type2: ObjectOrType): Promise<boolean>;
13
- createTable(type: Type): Promise<boolean>;
14
- implicitTableName(type1: ObjectOrType, type2: ObjectOrType): string;
15
- manageError(error: SqlError, context: Context, _sql: string | QueryOptions, _values: any[]): Promise<boolean>;
16
- updateContextTables(context: Context, tableName?: string): Promise<boolean>;
17
- updateTable(type: Type): Promise<boolean>;
18
- }
@@ -1,106 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MysqlMaintainer = exports.DEBUG = exports.Mysql = void 0;
4
- const class_type_1 = require("@itrocks/class-type");
5
- const mysql_1 = require("@itrocks/mysql");
6
- const mysql_to_schema_1 = require("@itrocks/mysql-to-schema");
7
- const reflect_to_schema_1 = require("@itrocks/reflect-to-schema");
8
- const schema_diff_1 = require("@itrocks/schema-diff");
9
- const schema_diff_mysql_1 = require("@itrocks/schema-diff-mysql");
10
- const schema_to_mysql_1 = require("@itrocks/schema-to-mysql");
11
- const store_1 = require("@itrocks/store");
12
- var mysql_2 = require("./mysql");
13
- Object.defineProperty(exports, "Mysql", { enumerable: true, get: function () { return mysql_2.Mysql; } });
14
- exports.DEBUG = false;
15
- const DELETION = false;
16
- class MysqlMaintainer {
17
- connection;
18
- constructor(connection) {
19
- this.connection = connection;
20
- }
21
- async createImplicitTable(type1, type2) {
22
- const joinTable = this.implicitTableName(type1, type2);
23
- const table1 = (0, store_1.storeOf)(type1);
24
- const table2 = (0, store_1.storeOf)(type2);
25
- const query = `CREATE TABLE \`${joinTable}\` (
26
- ${table1}_id int unsigned NOT NULL,
27
- ${table2}_id int unsigned NOT NULL,
28
- PRIMARY KEY (${table1}_id, ${table2}_id),
29
- CONSTRAINT \`${joinTable}.${table1}_id\` FOREIGN KEY (${table1}_id) REFERENCES \`${table1}\` (id) ON DELETE CASCADE ON UPDATE CASCADE,
30
- CONSTRAINT \`${joinTable}.${table2}_id\` FOREIGN KEY (${table2}_id) REFERENCES \`${table2}\` (id) ON DELETE CASCADE ON UPDATE CASCADE
31
- )`;
32
- await this.connection.query(query);
33
- return true;
34
- }
35
- async createTable(type) {
36
- const tableName = (0, store_1.storeOf)(type);
37
- if (!tableName) {
38
- throw 'No table name for type';
39
- }
40
- const tableSchema = new reflect_to_schema_1.ReflectToTable().convert(type);
41
- const schemaToMysql = new schema_to_mysql_1.SchemaToMysql();
42
- const sql = schemaToMysql.sql(tableSchema);
43
- await this.connection.query(sql);
44
- return true;
45
- }
46
- implicitTableName(type1, type2) {
47
- const table1 = (0, store_1.storeOf)(type1);
48
- const table2 = (0, store_1.storeOf)(type2);
49
- if (!table1 || !table2) {
50
- throw 'Collection objects are not stored';
51
- }
52
- return (0, mysql_1.joinTableName)(table1, table2);
53
- }
54
- async manageError(error, context, _sql, _values) {
55
- if (exports.DEBUG)
56
- console.log('MAINTAINER: manageError', error);
57
- switch (error.code) {
58
- case 'ER_BAD_FIELD_ERROR':
59
- case 'ER_CANNOT_ADD_FOREIGN':
60
- return this.updateContextTables(context);
61
- case 'ER_NO_SUCH_TABLE':
62
- const tableName = /Table '.*?\.(.*?)'/.exec(error.message)?.[1];
63
- return this.updateContextTables(context, tableName);
64
- }
65
- return false;
66
- }
67
- async updateContextTables(context, tableName) {
68
- let result = false;
69
- const contexts = Array.isArray(context) ? context : [context];
70
- for (const context of contexts) {
71
- const type = (0, class_type_1.typeOf)(context);
72
- const tableName = (0, store_1.storeOf)(type);
73
- if (!tableName) {
74
- throw 'No table name for type';
75
- }
76
- const exists = (await this.connection.query('SHOW TABLES LIKE ?', tableName));
77
- result ||= await (exists.length ? this.updateTable(type) : this.createTable(type));
78
- }
79
- if ((contexts.length === 2) && (this.implicitTableName(contexts[0], contexts[1]) === tableName)) {
80
- result ||= await this.createImplicitTable(contexts[0], contexts[1]);
81
- }
82
- return result;
83
- }
84
- async updateTable(type) {
85
- const tableName = (0, store_1.storeOf)(type);
86
- if (!tableName) {
87
- throw 'No table name for type';
88
- }
89
- const classTable = new reflect_to_schema_1.ReflectToTable().convert(type);
90
- new mysql_to_schema_1.MysqlToTable(this.connection).normalize(classTable);
91
- const mysqlTable = await ((new mysql_to_schema_1.MysqlToTable(this.connection)).convert(tableName));
92
- const schemaDiff = new schema_diff_1.TableDiff(mysqlTable, classTable);
93
- if (!schemaDiff.additions.length
94
- && !schemaDiff.changes.length
95
- && (!schemaDiff.deletions.length || !DELETION)
96
- && !schemaDiff.tableChanges()) {
97
- return false;
98
- }
99
- const schemaDiffMysql = new schema_diff_mysql_1.SchemaDiffMysql();
100
- const sql = schemaDiffMysql.sql(schemaDiff, DELETION);
101
- await this.connection.query(sql);
102
- return true;
103
- }
104
- }
105
- exports.MysqlMaintainer = MysqlMaintainer;
106
- //# sourceMappingURL=mysql-maintainer.js.map
package/cjs/mysql.d.ts DELETED
@@ -1,26 +0,0 @@
1
- import { ObjectOrType } from '@itrocks/class-type';
2
- import { Type } from '@itrocks/class-type';
3
- import { Mysql as M } from '@itrocks/mysql';
4
- import { Entity } from '@itrocks/storage';
5
- import { Identifier } from '@itrocks/storage';
6
- import { MayEntity } from '@itrocks/storage';
7
- import { Options } from '@itrocks/storage';
8
- import { SearchType } from '@itrocks/storage';
9
- import { ContextualConnection } from './contextual-connection';
10
- export declare class Mysql extends M {
11
- connection?: ContextualConnection;
12
- connect(): Promise<ContextualConnection>;
13
- deleteId<T extends object>(type: ObjectOrType<T>, id: any, property?: keyof Entity<T>): Promise<void>;
14
- deleteRelatedId<T extends Entity>(object: T, property: keyof T, id: Identifier): Promise<void>;
15
- insert<T extends object>(object: T): Promise<Entity<T>>;
16
- insertRelatedId<T extends Entity>(object: T, property: keyof T, id: Identifier): Promise<void>;
17
- read<T extends object>(type: Type<T>, id: Identifier): Promise<Entity<T>>;
18
- readCollection<T extends object, PT extends object>(object: Entity<T>, property: keyof T, type?: Type<PT>): Promise<Awaited<PT & {
19
- id: Identifier;
20
- }>[]>;
21
- readCollectionIds<T extends object, PT extends object>(object: Entity<T>, property: keyof T, type?: Type<PT>): Promise<Identifier[]>;
22
- readMultiple<T extends object>(type: Type<T>, ids: Identifier[]): Promise<Entity<T>[]>;
23
- save<T extends object>(object: MayEntity<T>): Promise<Entity<T>>;
24
- search<T extends object>(type: Type<T>, search?: SearchType<T>, options?: Options): Promise<Entity<T>[]>;
25
- update<T extends object>(object: Entity<T>): Promise<Entity<T>>;
26
- }
package/cjs/mysql.js DELETED
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Mysql = void 0;
4
- const mysql_1 = require("@itrocks/mysql");
5
- const reflect_1 = require("@itrocks/reflect");
6
- const contextual_connection_1 = require("./contextual-connection");
7
- class Mysql extends mysql_1.Mysql {
8
- async connect() {
9
- return contextual_connection_1.Contextual.prototype.applyTo(await super.connect());
10
- }
11
- async deleteId(type, id, property = 'id') {
12
- const contexts = (this.connection ?? await this.connect()).contexts;
13
- contexts.push(type);
14
- const result = await super.deleteId(type, id, property);
15
- contexts.pop();
16
- return result;
17
- }
18
- async deleteRelatedId(object, property, id) {
19
- const contexts = (this.connection ?? await this.connect()).contexts;
20
- contexts.push(object);
21
- const result = await super.deleteRelatedId(object, property, id);
22
- contexts.pop();
23
- return result;
24
- }
25
- async insert(object) {
26
- const contexts = (this.connection ?? await this.connect()).contexts;
27
- contexts.push(object);
28
- const result = await super.insert(object);
29
- contexts.pop();
30
- return result;
31
- }
32
- async insertRelatedId(object, property, id) {
33
- const contexts = (this.connection ?? await this.connect()).contexts;
34
- contexts.push(object);
35
- const result = await super.insertRelatedId(object, property, id);
36
- contexts.pop();
37
- return result;
38
- }
39
- async read(type, id) {
40
- const contexts = (this.connection ?? await this.connect()).contexts;
41
- contexts.push(type);
42
- const result = await super.read(type, id);
43
- contexts.pop();
44
- return result;
45
- }
46
- async readCollection(object, property, type) {
47
- type ??= new reflect_1.ReflectProperty(object, property).collectionType.elementType.type;
48
- const contexts = (this.connection ?? await this.connect()).contexts;
49
- contexts.push([object, type]);
50
- const result = await super.readCollection(object, property, type);
51
- contexts.pop();
52
- return result;
53
- }
54
- async readCollectionIds(object, property, type) {
55
- type ??= new reflect_1.ReflectProperty(object, property).collectionType.elementType.type;
56
- const contexts = (this.connection ?? await this.connect()).contexts;
57
- contexts.push([object, type]);
58
- const result = await super.readCollectionIds(object, property, type);
59
- contexts.pop();
60
- return result;
61
- }
62
- async readMultiple(type, ids) {
63
- const contexts = (this.connection ?? await this.connect()).contexts;
64
- contexts.push(type);
65
- const result = await super.readMultiple(type, ids);
66
- contexts.pop();
67
- return result;
68
- }
69
- async save(object) {
70
- const contexts = (this.connection ?? await this.connect()).contexts;
71
- contexts.push(object);
72
- const result = await super.save(object);
73
- contexts.pop();
74
- return result;
75
- }
76
- async search(type, search = {}, options) {
77
- const contexts = (this.connection ?? await this.connect()).contexts;
78
- contexts.push(type);
79
- const result = await super.search(type, search, options);
80
- contexts.pop();
81
- return result;
82
- }
83
- async update(object) {
84
- const contexts = (this.connection ?? await this.connect()).contexts;
85
- contexts.push(object);
86
- const result = await super.update(object);
87
- contexts.pop();
88
- return result;
89
- }
90
- }
91
- exports.Mysql = Mysql;
92
- //# sourceMappingURL=mysql.js.map