@itrocks/mysql-maintainer 0.0.9 → 0.0.10

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.
@@ -3,7 +3,7 @@ import { Connection } from 'mariadb';
3
3
  import { QueryOptions } from 'mariadb';
4
4
  export type Context = ObjectOrType | ObjectOrType[];
5
5
  export declare class Contextual implements Partial<Connection> {
6
- context: Context[];
6
+ contexts: Context[];
7
7
  superQuery: <T = any>(sql: string | QueryOptions, values?: any) => Promise<T>;
8
8
  applyTo(connection: ContextualConnection): Promise<ContextualConnection>;
9
9
  query<T = any>(sql: string | QueryOptions, values?: any): Promise<T>;
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Contextual = void 0;
4
4
  const mariadb_1 = require("mariadb");
5
5
  const mysql_maintainer_1 = require("./mysql-maintainer");
6
- const MANAGED_ERROR_CODES = ['ER_BAD_FIELD_ERROR', 'ER_CANNOT_ADD_FOREIGN', 'ER_CANT_CREATE_TABLE', 'ER_NO_SUCH_TABLE'];
6
+ const MANAGED_ERROR_CODES = ['ER_BAD_FIELD_ERROR', 'ER_CANNOT_ADD_FOREIGN', 'ER_NO_SUCH_TABLE'];
7
7
  class Contextual {
8
- context = [];
8
+ contexts = [];
9
9
  superQuery = () => new Promise(() => { });
10
10
  async applyTo(connection) {
11
- connection.context = [];
11
+ connection.contexts = [];
12
12
  connection.superQuery = connection.query;
13
13
  connection.query = Contextual.prototype.query;
14
14
  return connection;
@@ -24,7 +24,7 @@ class Contextual {
24
24
  throw error;
25
25
  }
26
26
  // @ts-ignore query applies to a Connection
27
- if (await new mysql_maintainer_1.MysqlMaintainer(this).manageError(error, this.context[this.context.length - 1], sql, values)) {
27
+ if (await new mysql_maintainer_1.MysqlMaintainer(this).manageError(error, this.contexts[this.contexts.length - 1], sql, values)) {
28
28
  return this.query(sql, values);
29
29
  }
30
30
  throw error;
@@ -1,3 +1,4 @@
1
+ import { ObjectOrType } from '@itrocks/class-type';
1
2
  import { Type } from '@itrocks/class-type';
2
3
  import { Connection } from 'mariadb';
3
4
  import { QueryOptions } from 'mariadb';
@@ -7,7 +8,7 @@ export * from './mysql';
7
8
  export declare class MysqlMaintainer {
8
9
  connection: Connection;
9
10
  constructor(connection: Connection);
10
- createImplicitTables(sql: string | QueryOptions): boolean;
11
+ createImplicitTable(type1: ObjectOrType, type2: ObjectOrType): Promise<boolean>;
11
12
  createTable(type: Type): Promise<boolean>;
12
13
  manageError(error: SqlError, context: Context, sql: string | QueryOptions, values: any[]): Promise<boolean>;
13
14
  updateContextTables(context: Context): Promise<boolean>;
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.MysqlMaintainer = void 0;
18
18
  const class_type_1 = require("@itrocks/class-type");
19
+ const mysql_1 = require("@itrocks/mysql");
19
20
  const mysql_to_schema_1 = require("@itrocks/mysql-to-schema");
20
21
  const reflect_to_schema_1 = require("@itrocks/reflect-to-schema");
21
22
  const schema_diff_1 = require("@itrocks/schema-diff");
@@ -28,8 +29,21 @@ class MysqlMaintainer {
28
29
  constructor(connection) {
29
30
  this.connection = connection;
30
31
  }
31
- createImplicitTables(sql) {
32
- return false;
32
+ async createImplicitTable(type1, type2) {
33
+ const table1 = (0, store_1.storeOf)(type1);
34
+ const table2 = (0, store_1.storeOf)(type2);
35
+ if (!table1 || !table2) {
36
+ throw 'Collection objects are not stored';
37
+ }
38
+ const joinTable = (0, mysql_1.joinTableName)(table1, table2);
39
+ const query = 'CREATE TABLE `' + joinTable + '` (\n'
40
+ + '`' + table1 + '_id` bigint NOT NULL,\n'
41
+ + '`' + table2 + '_id` bigint NOT NULL,\n'
42
+ + 'PRIMARY KEY (`' + table1 + '_id`,`' + table2 + '_id`)'
43
+ + ')';
44
+ console.log(query);
45
+ await this.connection.query(query);
46
+ return true;
33
47
  }
34
48
  async createTable(type) {
35
49
  const tableName = (0, store_1.storeOf)(type);
@@ -51,8 +65,6 @@ class MysqlMaintainer {
51
65
  case 'ER_BAD_FIELD_ERROR':
52
66
  case 'ER_CANNOT_ADD_FOREIGN':
53
67
  return await this.updateContextTables(context);
54
- case 'ER_CANT_CREATE_TABLE':
55
- return this.createImplicitTables(sql);
56
68
  case 'ER_NO_SUCH_TABLE':
57
69
  return this.updateContextTables(context);
58
70
  }
@@ -67,7 +79,10 @@ class MysqlMaintainer {
67
79
  throw 'No table name for type';
68
80
  }
69
81
  const exists = (await this.connection.query('SHOW TABLES LIKE ?', tableName));
70
- await (exists.length ? this.updateTable(type) : this.createTable(type));
82
+ exists.length ? await this.updateTable(type) : await this.createTable(type);
83
+ }
84
+ if (contexts.length === 2) {
85
+ await this.createImplicitTable(contexts[0], contexts[1]);
71
86
  }
72
87
  return true;
73
88
  }
@@ -83,6 +98,9 @@ class MysqlMaintainer {
83
98
  console.dir(schemaDiff.additions, { depth: null });
84
99
  console.dir(schemaDiff.changes, { depth: null });
85
100
  console.dir(schemaDiff.deletions, { depth: null });
101
+ if (!schemaDiff.additions && !schemaDiff.changes && !schemaDiff.deletions && !schemaDiff.tableChanges()) {
102
+ return false;
103
+ }
86
104
  const schemaDiffMysql = new schema_diff_mysql_1.SchemaDiffMysql();
87
105
  const sql = schemaDiffMysql.sql(schemaDiff, true);
88
106
  await this.connection.query(sql);
package/cjs/mysql.js CHANGED
@@ -9,73 +9,73 @@ class Mysql extends mysql_1.Mysql {
9
9
  return contextual_connection_1.Contextual.prototype.applyTo(await super.connect());
10
10
  }
11
11
  async deleteId(type, id, property = 'id') {
12
- const context = (this.connection ?? await this.connect()).context;
13
- context.push(type);
12
+ const contexts = (this.connection ?? await this.connect()).contexts;
13
+ contexts.push(type);
14
14
  const result = await super.deleteId(type, id, property);
15
- context.pop();
15
+ contexts.pop();
16
16
  return result;
17
17
  }
18
18
  async deleteRelatedId(object, property, id) {
19
- const context = (this.connection ?? await this.connect()).context;
20
- context.push(object);
19
+ const contexts = (this.connection ?? await this.connect()).contexts;
20
+ contexts.push(object);
21
21
  const result = await super.deleteRelatedId(object, property, id);
22
- context.pop();
22
+ contexts.pop();
23
23
  return result;
24
24
  }
25
25
  async insert(object) {
26
- const context = (this.connection ?? await this.connect()).context;
27
- context.push(object);
26
+ const contexts = (this.connection ?? await this.connect()).contexts;
27
+ contexts.push(object);
28
28
  const result = await super.insert(object);
29
- context.pop();
29
+ contexts.pop();
30
30
  return result;
31
31
  }
32
32
  async insertRelatedId(object, property, id) {
33
- const context = (this.connection ?? await this.connect()).context;
34
- context.push(object);
33
+ const contexts = (this.connection ?? await this.connect()).contexts;
34
+ contexts.push(object);
35
35
  const result = await super.insertRelatedId(object, property, id);
36
- context.pop();
36
+ contexts.pop();
37
37
  return result;
38
38
  }
39
39
  async read(type, id) {
40
- const context = (this.connection ?? await this.connect()).context;
41
- context.push(type);
40
+ const contexts = (this.connection ?? await this.connect()).contexts;
41
+ contexts.push(type);
42
42
  const result = await super.read(type, id);
43
- context.pop();
43
+ contexts.pop();
44
44
  return result;
45
45
  }
46
46
  async readCollection(object, property, type = new reflect_1.ReflectProperty(object, property).collectionType.elementType.type) {
47
- const context = (this.connection ?? await this.connect()).context;
48
- context.push([object, type]);
47
+ const contexts = (this.connection ?? await this.connect()).contexts;
48
+ contexts.push([object, type]);
49
49
  const result = await super.readCollection(object, property, type);
50
- context.pop();
50
+ contexts.pop();
51
51
  return result;
52
52
  }
53
53
  async readCollectionIds(object, property, type = new reflect_1.ReflectProperty(object, property).collectionType.elementType.type) {
54
- const context = (this.connection ?? await this.connect()).context;
55
- context.push([object, type]);
54
+ const contexts = (this.connection ?? await this.connect()).contexts;
55
+ contexts.push([object, type]);
56
56
  const result = await super.readCollectionIds(object, property, type);
57
- context.pop();
57
+ contexts.pop();
58
58
  return result;
59
59
  }
60
60
  async readMultiple(type, ids) {
61
- const context = (this.connection ?? await this.connect()).context;
62
- context.push(type);
61
+ const contexts = (this.connection ?? await this.connect()).contexts;
62
+ contexts.push(type);
63
63
  const result = await super.readMultiple(type, ids);
64
- context.pop();
64
+ contexts.pop();
65
65
  return result;
66
66
  }
67
67
  async search(type, search = {}) {
68
- const context = (this.connection ?? await this.connect()).context;
69
- context.push(type);
68
+ const contexts = (this.connection ?? await this.connect()).contexts;
69
+ contexts.push(type);
70
70
  const result = await super.search(type, search);
71
- context.pop();
71
+ contexts.pop();
72
72
  return result;
73
73
  }
74
74
  async update(object) {
75
- const context = (this.connection ?? await this.connect()).context;
76
- context.push(object);
75
+ const contexts = (this.connection ?? await this.connect()).contexts;
76
+ contexts.push(object);
77
77
  const result = await super.update(object);
78
- context.pop();
78
+ contexts.pop();
79
79
  return result;
80
80
  }
81
81
  }
@@ -3,7 +3,7 @@ import { Connection } from 'mariadb';
3
3
  import { QueryOptions } from 'mariadb';
4
4
  export type Context = ObjectOrType | ObjectOrType[];
5
5
  export declare class Contextual implements Partial<Connection> {
6
- context: Context[];
6
+ contexts: Context[];
7
7
  superQuery: <T = any>(sql: string | QueryOptions, values?: any) => Promise<T>;
8
8
  applyTo(connection: ContextualConnection): Promise<ContextualConnection>;
9
9
  query<T = any>(sql: string | QueryOptions, values?: any): Promise<T>;
@@ -1,11 +1,11 @@
1
1
  import { SqlError } from 'mariadb';
2
2
  import { MysqlMaintainer } from './mysql-maintainer';
3
- const MANAGED_ERROR_CODES = ['ER_BAD_FIELD_ERROR', 'ER_CANNOT_ADD_FOREIGN', 'ER_CANT_CREATE_TABLE', 'ER_NO_SUCH_TABLE'];
3
+ const MANAGED_ERROR_CODES = ['ER_BAD_FIELD_ERROR', 'ER_CANNOT_ADD_FOREIGN', 'ER_NO_SUCH_TABLE'];
4
4
  export class Contextual {
5
- context = [];
5
+ contexts = [];
6
6
  superQuery = () => new Promise(() => { });
7
7
  async applyTo(connection) {
8
- connection.context = [];
8
+ connection.contexts = [];
9
9
  connection.superQuery = connection.query;
10
10
  connection.query = Contextual.prototype.query;
11
11
  return connection;
@@ -21,7 +21,7 @@ export class Contextual {
21
21
  throw error;
22
22
  }
23
23
  // @ts-ignore query applies to a Connection
24
- if (await new MysqlMaintainer(this).manageError(error, this.context[this.context.length - 1], sql, values)) {
24
+ if (await new MysqlMaintainer(this).manageError(error, this.contexts[this.contexts.length - 1], sql, values)) {
25
25
  return this.query(sql, values);
26
26
  }
27
27
  throw error;
@@ -1,3 +1,4 @@
1
+ import { ObjectOrType } from '@itrocks/class-type';
1
2
  import { Type } from '@itrocks/class-type';
2
3
  import { Connection } from 'mariadb';
3
4
  import { QueryOptions } from 'mariadb';
@@ -7,7 +8,7 @@ export * from './mysql';
7
8
  export declare class MysqlMaintainer {
8
9
  connection: Connection;
9
10
  constructor(connection: Connection);
10
- createImplicitTables(sql: string | QueryOptions): boolean;
11
+ createImplicitTable(type1: ObjectOrType, type2: ObjectOrType): Promise<boolean>;
11
12
  createTable(type: Type): Promise<boolean>;
12
13
  manageError(error: SqlError, context: Context, sql: string | QueryOptions, values: any[]): Promise<boolean>;
13
14
  updateContextTables(context: Context): Promise<boolean>;
@@ -1,4 +1,5 @@
1
1
  import { typeOf } from '@itrocks/class-type';
2
+ import { joinTableName } from '@itrocks/mysql';
2
3
  import { MysqlToTable } from '@itrocks/mysql-to-schema';
3
4
  import { ReflectToTable } from '@itrocks/reflect-to-schema';
4
5
  import { TableDiff } from '@itrocks/schema-diff';
@@ -11,8 +12,21 @@ export class MysqlMaintainer {
11
12
  constructor(connection) {
12
13
  this.connection = connection;
13
14
  }
14
- createImplicitTables(sql) {
15
- return false;
15
+ async createImplicitTable(type1, type2) {
16
+ const table1 = storeOf(type1);
17
+ const table2 = storeOf(type2);
18
+ if (!table1 || !table2) {
19
+ throw 'Collection objects are not stored';
20
+ }
21
+ const joinTable = joinTableName(table1, table2);
22
+ const query = 'CREATE TABLE `' + joinTable + '` (\n'
23
+ + '`' + table1 + '_id` bigint NOT NULL,\n'
24
+ + '`' + table2 + '_id` bigint NOT NULL,\n'
25
+ + 'PRIMARY KEY (`' + table1 + '_id`,`' + table2 + '_id`)'
26
+ + ')';
27
+ console.log(query);
28
+ await this.connection.query(query);
29
+ return true;
16
30
  }
17
31
  async createTable(type) {
18
32
  const tableName = storeOf(type);
@@ -34,8 +48,6 @@ export class MysqlMaintainer {
34
48
  case 'ER_BAD_FIELD_ERROR':
35
49
  case 'ER_CANNOT_ADD_FOREIGN':
36
50
  return await this.updateContextTables(context);
37
- case 'ER_CANT_CREATE_TABLE':
38
- return this.createImplicitTables(sql);
39
51
  case 'ER_NO_SUCH_TABLE':
40
52
  return this.updateContextTables(context);
41
53
  }
@@ -50,7 +62,10 @@ export class MysqlMaintainer {
50
62
  throw 'No table name for type';
51
63
  }
52
64
  const exists = (await this.connection.query('SHOW TABLES LIKE ?', tableName));
53
- await (exists.length ? this.updateTable(type) : this.createTable(type));
65
+ exists.length ? await this.updateTable(type) : await this.createTable(type);
66
+ }
67
+ if (contexts.length === 2) {
68
+ await this.createImplicitTable(contexts[0], contexts[1]);
54
69
  }
55
70
  return true;
56
71
  }
@@ -66,6 +81,9 @@ export class MysqlMaintainer {
66
81
  console.dir(schemaDiff.additions, { depth: null });
67
82
  console.dir(schemaDiff.changes, { depth: null });
68
83
  console.dir(schemaDiff.deletions, { depth: null });
84
+ if (!schemaDiff.additions && !schemaDiff.changes && !schemaDiff.deletions && !schemaDiff.tableChanges()) {
85
+ return false;
86
+ }
69
87
  const schemaDiffMysql = new SchemaDiffMysql();
70
88
  const sql = schemaDiffMysql.sql(schemaDiff, true);
71
89
  await this.connection.query(sql);
package/esm/mysql.js CHANGED
@@ -6,73 +6,73 @@ export class Mysql extends M {
6
6
  return Contextual.prototype.applyTo(await super.connect());
7
7
  }
8
8
  async deleteId(type, id, property = 'id') {
9
- const context = (this.connection ?? await this.connect()).context;
10
- context.push(type);
9
+ const contexts = (this.connection ?? await this.connect()).contexts;
10
+ contexts.push(type);
11
11
  const result = await super.deleteId(type, id, property);
12
- context.pop();
12
+ contexts.pop();
13
13
  return result;
14
14
  }
15
15
  async deleteRelatedId(object, property, id) {
16
- const context = (this.connection ?? await this.connect()).context;
17
- context.push(object);
16
+ const contexts = (this.connection ?? await this.connect()).contexts;
17
+ contexts.push(object);
18
18
  const result = await super.deleteRelatedId(object, property, id);
19
- context.pop();
19
+ contexts.pop();
20
20
  return result;
21
21
  }
22
22
  async insert(object) {
23
- const context = (this.connection ?? await this.connect()).context;
24
- context.push(object);
23
+ const contexts = (this.connection ?? await this.connect()).contexts;
24
+ contexts.push(object);
25
25
  const result = await super.insert(object);
26
- context.pop();
26
+ contexts.pop();
27
27
  return result;
28
28
  }
29
29
  async insertRelatedId(object, property, id) {
30
- const context = (this.connection ?? await this.connect()).context;
31
- context.push(object);
30
+ const contexts = (this.connection ?? await this.connect()).contexts;
31
+ contexts.push(object);
32
32
  const result = await super.insertRelatedId(object, property, id);
33
- context.pop();
33
+ contexts.pop();
34
34
  return result;
35
35
  }
36
36
  async read(type, id) {
37
- const context = (this.connection ?? await this.connect()).context;
38
- context.push(type);
37
+ const contexts = (this.connection ?? await this.connect()).contexts;
38
+ contexts.push(type);
39
39
  const result = await super.read(type, id);
40
- context.pop();
40
+ contexts.pop();
41
41
  return result;
42
42
  }
43
43
  async readCollection(object, property, type = new ReflectProperty(object, property).collectionType.elementType.type) {
44
- const context = (this.connection ?? await this.connect()).context;
45
- context.push([object, type]);
44
+ const contexts = (this.connection ?? await this.connect()).contexts;
45
+ contexts.push([object, type]);
46
46
  const result = await super.readCollection(object, property, type);
47
- context.pop();
47
+ contexts.pop();
48
48
  return result;
49
49
  }
50
50
  async readCollectionIds(object, property, type = new ReflectProperty(object, property).collectionType.elementType.type) {
51
- const context = (this.connection ?? await this.connect()).context;
52
- context.push([object, type]);
51
+ const contexts = (this.connection ?? await this.connect()).contexts;
52
+ contexts.push([object, type]);
53
53
  const result = await super.readCollectionIds(object, property, type);
54
- context.pop();
54
+ contexts.pop();
55
55
  return result;
56
56
  }
57
57
  async readMultiple(type, ids) {
58
- const context = (this.connection ?? await this.connect()).context;
59
- context.push(type);
58
+ const contexts = (this.connection ?? await this.connect()).contexts;
59
+ contexts.push(type);
60
60
  const result = await super.readMultiple(type, ids);
61
- context.pop();
61
+ contexts.pop();
62
62
  return result;
63
63
  }
64
64
  async search(type, search = {}) {
65
- const context = (this.connection ?? await this.connect()).context;
66
- context.push(type);
65
+ const contexts = (this.connection ?? await this.connect()).contexts;
66
+ contexts.push(type);
67
67
  const result = await super.search(type, search);
68
- context.pop();
68
+ contexts.pop();
69
69
  return result;
70
70
  }
71
71
  async update(object) {
72
- const context = (this.connection ?? await this.connect()).context;
73
- context.push(object);
72
+ const contexts = (this.connection ?? await this.connect()).contexts;
73
+ contexts.push(object);
74
74
  const result = await super.update(object);
75
- context.pop();
75
+ contexts.pop();
76
76
  return result;
77
77
  }
78
78
  }
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  "build:esm": "tsc -p tsconfig.esm.json"
55
55
  },
56
56
  "types": "./esm/mysql-maintainer.d.ts",
57
- "version": "0.0.9"
57
+ "version": "0.0.10"
58
58
  }