gg-mysql-connector 1.0.10 → 1.0.12

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 ADDED
@@ -0,0 +1,118 @@
1
+ # gg-mysql-connector
2
+
3
+ **`gg-mysql-connector`** is an intuitive MySQL model creator designed to simplify database management and operations by synchronizing TypeScript models with MySQL tables. This package allows you to declare and manage your MySQL database structure programmatically, with strong type enforcement.
4
+
5
+ ## Features
6
+
7
+ - **Declare Database Structure**: Define your database tables and columns as TypeScript variables.
8
+ - **Sync Database Structure**: Automatically synchronize your declared models with the actual MySQL database.
9
+ - **Automated View Management**: Automatically create or update SQL views based on your declarations.
10
+ - **Generate TypeScript Models**: Generate interfaces that mirror your MySQL structure, ensuring type-safe operations.
11
+ - **Type-Safe MySQL Connector**: Provides type-enforced MySQL operations like CRUD (Select, Update, Delete).
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install gg-mysql-connector
17
+ ```
18
+
19
+ ## 1. Declare Your Model
20
+
21
+ Start by declaring your database tables and columns as TypeScript variables:
22
+
23
+ ```typescript
24
+ import { MyModel } from "gg-mysql-connector"
25
+
26
+ const model: MyModel[] = [
27
+ {
28
+ tableName: "user",
29
+ columns: [
30
+ { COLUMN_NAME: "id", DATA_TYPE: "int", AUTO_INCREMENT: true },
31
+ { COLUMN_NAME: "name", DATA_TYPE: "varchar(512)" },
32
+ ],
33
+ },
34
+ {
35
+ tableName: "item",
36
+ columns: [
37
+ { COLUMN_NAME: "id", DATA_TYPE: "int", AUTO_INCREMENT: true },
38
+ { COLUMN_NAME: "name", DATA_TYPE: "varchar(512)" },
39
+ { COLUMN_NAME: "price", DATA_TYPE: "float" },
40
+ {
41
+ COLUMN_NAME: "status",
42
+ DATA_TYPE: "varchar(64)",
43
+ POSSIBLE_VALUE: ["ACTIVE", "DISABLE"],
44
+ },
45
+ { COLUMN_NAME: "description", DATA_TYPE: "varchar(512)" },
46
+ ],
47
+ },
48
+ ]
49
+ ```
50
+
51
+ ## 2. Sync Model and Views with MySQL & Generate Model Interface
52
+
53
+ Use the provided functions to sync your model with MySQL and generate TypeScript interfaces.
54
+
55
+ ```typescript
56
+ import { ModelGenerator } from "gg-mysql-connector"
57
+
58
+ const migrator = new ModelGenerator(
59
+ {
60
+ host: "your-host",
61
+ user: "your-user",
62
+ password: "your-password",
63
+ database: "test_ggdb_connector",
64
+ },
65
+ model
66
+ )
67
+
68
+ await migrator.init()
69
+ await migrator.pushModelToDB()
70
+ await migrator.pushViewToDB("./views")
71
+ await migrator.generateModelInterface({
72
+ appName: "app",
73
+ model: model,
74
+ outputDirectory: ["./"],
75
+ })
76
+
77
+ process.exit()
78
+ ```
79
+
80
+ ## 3. CRUD Operations with Type Enforcement
81
+
82
+ Once you've generated your interfaces, you can perform type-enforced MySQL operations.
83
+
84
+ ```typescript
85
+ import GGMySQLConnector from "gg-mysql-connector"
86
+ import app_INF from "./your-output-directory/app_INF" // Generated in step 2
87
+
88
+ const db = new GGMySQLConnector<app_INF>({
89
+ host: "your-host",
90
+ user: "your-user",
91
+ password: "your-password",
92
+ database: "test_ggdb_connector",
93
+ })
94
+
95
+ await db.init()
96
+
97
+ // Select operations
98
+ let result_1 = await db.select("item")
99
+ let result_2 = await db.selectByID("user", 2)
100
+ let result_3 = await db.selectByMatchParams("item", { id: 5 })
101
+ let result_4 = await db.selectByMatchParams("item", { name: "pen", price: 3 })
102
+
103
+ // Update operations
104
+ let result_5 = await db.update("user", { id: 3, name: "Tony" })
105
+ let result_6 = await db.update("item", { id: 3, price: 4, name: "Ruler" })
106
+ let result_7 = await db.updateOnlyID("item", { oldID: 7, newID: 4 })
107
+
108
+ // Delete operations
109
+ let result_8 = await db.deleteByID("item", 5)
110
+ let result_9 = await db.deleteByMatchParams("item", { name: "pen", price: 5 })
111
+
112
+ // raw query
113
+ const result_10 = await db.query("SELECT * FROM item where id = ?", [5])
114
+ ```
115
+
116
+ ## License
117
+
118
+ MIT License
@@ -45,10 +45,10 @@ export default class GGMySQLConnector<Main> implements ClassDBInterface<Main> {
45
45
  select<T extends keyof Main>(tableName: T extends string ? T : string): Promise<Main[T][]>;
46
46
  getTableNameList(): Promise<string[]>;
47
47
  getViewNameList(): Promise<string[]>;
48
- deleteByMatchParams<T>(tableName: string, params: Partial<{
49
- [K in keyof Unarray<T>]: string | number | undefined | null;
48
+ deleteByMatchParams<T extends keyof Main>(tableName: T extends string ? T : string, params: Partial<{
49
+ [K in keyof Main[T]]: T | string | number | undefined | null;
50
50
  }>): Promise<mysql.OkPacket | null>;
51
- deleteByID(tableName: string, id: number): Promise<mysql.OkPacket>;
51
+ deleteByID<T extends keyof Main>(tableName: T extends string ? T : string, id: number): Promise<mysql.OkPacket>;
52
52
  insert<T extends keyof Main>(tableName: T, parameter: Partial<{
53
53
  [R in keyof Unarray<Main[T]>]: any;
54
54
  }> | Partial<{
@@ -20,5 +20,9 @@ export default class ModelGenerator {
20
20
  getTableNameList(): Promise<string[]>;
21
21
  getViewNameList(): Promise<string[]>;
22
22
  getColumnFullList(tableName: string): Promise<mysql.RowDataPacket[]>;
23
- generateModelInterface(DBType: string, model: MyModel[], ouputDirectory: string[]): Promise<string>;
23
+ generateModelInterface(params: {
24
+ appName: string;
25
+ model: MyModel[];
26
+ ouputDirectory: string[];
27
+ }): Promise<string>;
24
28
  }
@@ -90,11 +90,11 @@ class ModelGenerator {
90
90
  const result = (await this.query(`SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${this.dbInfo.database}' AND TABLE_NAME = '${tableName}'`, undefined, false));
91
91
  return result;
92
92
  }
93
- async generateModelInterface(DBType, model, ouputDirectory) {
93
+ async generateModelInterface(params) {
94
94
  const isTableNameExistInModel = (tableName) => {
95
95
  if (tableName === "sessions")
96
96
  return true;
97
- const table = model.find((row) => row.tableName === tableName);
97
+ const table = params.model.find((row) => row.tableName === tableName);
98
98
  if (table)
99
99
  return true;
100
100
  return false;
@@ -102,7 +102,7 @@ class ModelGenerator {
102
102
  const isColumnExistInModel = (tableName, columnName) => {
103
103
  if (tableName === "sessions")
104
104
  return true;
105
- const table = model.find((row) => row.tableName === tableName);
105
+ const table = params.model.find((row) => row.tableName === tableName);
106
106
  if (table) {
107
107
  const column = table.columns.find((row) => row.COLUMN_NAME === columnName);
108
108
  if (column)
@@ -111,7 +111,7 @@ class ModelGenerator {
111
111
  return false;
112
112
  };
113
113
  const getPossibleColumnValue = (tableName, columnName) => {
114
- const foundTable = model.find((row) => row.tableName === tableName);
114
+ const foundTable = params.model.find((row) => row.tableName === tableName);
115
115
  if (foundTable) {
116
116
  const foundColumn = foundTable["columns"].find((row) => row.COLUMN_NAME === columnName);
117
117
  if (foundColumn) {
@@ -153,14 +153,14 @@ class ModelGenerator {
153
153
  // console.log(`generate interface from ${tableName}`)
154
154
  }
155
155
  }
156
- const fileName = `${DBType}_INF.ts`;
157
- const code = `export default interface ${DBType}_INF { ${array.join("\n")} }`;
158
- ouputDirectory.forEach(async (tempPath) => {
156
+ const fileName = `${params.appName}_INF.ts`;
157
+ const code = `export default interface ${params.appName}_INF { ${array.join("\n")} }`;
158
+ params.ouputDirectory.forEach(async (tempPath) => {
159
159
  const serverFilePath = path_1.default.join(tempPath, fileName);
160
160
  await fs_1.default.writeFileSync(serverFilePath, code);
161
161
  console.log("save to ", serverFilePath);
162
162
  });
163
- console.log(`generate interface ${DBType} ${chalk_1.default.bgGreen(" SUCCESS ")}`);
163
+ console.log(`generate interface ${params.appName} ${chalk_1.default.bgGreen(" SUCCESS ")}`);
164
164
  return code;
165
165
  }
166
166
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gg-mysql-connector",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/readme2.md ADDED
@@ -0,0 +1,117 @@
1
+ # gg-mysql-connector
2
+
3
+ gg-mysql-connector is an intuitive MySQL model creator designed to simplify database management and operations by synchronizing TypeScript models with MySQL tables. This package allows you to declare and manage your MySQL database structure programmatically while enforcing strong type constraints.
4
+
5
+ Features
6
+
7
+ • Declare Database Structure: Easily define your database tables and columns as TypeScript variables.
8
+ • Sync Database Structure: Automatically synchronize your defined structures with the actual MySQL database.
9
+ • Automated View Management: Automatically create or update SQL views based on your declarations.
10
+ • Generate TypeScript Models: Generate interfaces that mirror your MySQL structure, ensuring type-safe operations.
11
+ • Type-Safe MySQL Connector: Provides a type-enforced MySQL connector with basic functions such as:
12
+ • Performing CRUD operations (Select, Update, Delete)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install gg-mysql-connector
18
+ ```
19
+
20
+ ## 1. Declare your model
21
+
22
+ ```typescript
23
+ import { MyModel } from "../myModel"
24
+
25
+ const model: MyModel[] = [
26
+ {
27
+ tableName: "user",
28
+ columns: [
29
+ {
30
+ COLUMN_NAME: "id",
31
+ DATA_TYPE: "int",
32
+ AUTO_INCREMENT: true,
33
+ },
34
+ {
35
+ COLUMN_NAME: "name",
36
+ DATA_TYPE: "varchar(512)",
37
+ },
38
+ ],
39
+ },
40
+ {
41
+ tableName: "item",
42
+ columns: [
43
+ {
44
+ COLUMN_NAME: "id",
45
+ DATA_TYPE: "int",
46
+ AUTO_INCREMENT: true,
47
+ },
48
+ {
49
+ COLUMN_NAME: "name",
50
+ DATA_TYPE: "varchar(512)",
51
+ },
52
+ {
53
+ COLUMN_NAME: "price",
54
+ DATA_TYPE: "float",
55
+ },
56
+ {
57
+ COLUMN_NAME: "status",
58
+ DATA_TYPE: "varchar(64)",
59
+ POSSIBLE_VALUE: ["ACTIVE", "DISABLE"],
60
+ },
61
+ {
62
+ COLUMN_NAME: "description",
63
+ DATA_TYPE: "varchar(512)",
64
+ },
65
+ ],
66
+ },
67
+ ]
68
+ ```
69
+
70
+ ## 2. Sync model and views to mysql and generate model interface file
71
+
72
+ ```typescript
73
+ const migrator = new ModelGenerator(
74
+ {
75
+ host: "you-host",
76
+ user: "user",
77
+ password: "password",
78
+ database: "test_ggdb_connector",
79
+ },
80
+ model
81
+ )
82
+ await migrator.init()
83
+ await migrator.pushModelToDB()
84
+ await migrator.pushViewToDB("./views")
85
+ await migrator.generateModelInterface({
86
+ appName: "app",
87
+ model: model,
88
+ ouputDirectory: ["./"],
89
+ })
90
+ process.exit()
91
+ ```
92
+
93
+ ## 3. CRUD with type enforced
94
+
95
+ ```typescript
96
+ // app_INF is an interface that you generated from step 2
97
+ import app_INF from "your-output-directory/app_INF"
98
+ const db = new GGMySQLConnector<app_INF>({
99
+ host: "you-host",
100
+ user: "user",
101
+ password: "password",
102
+ database: "test_ggdb_connector",
103
+ })
104
+ await db.init()
105
+
106
+ let result_1 = await db.select("item")
107
+ let result_2 = await db.selectByID("user", 2)
108
+ let result_3 = await db.selectByMatchParams("item", { id: 5 })
109
+ let result_4 = await db.selectByMatchParams("item", { name: "pen", price: 3 })
110
+
111
+ let result_5 = await db.update("user", { id: 3, name: "tony" })
112
+ let result_6 = await db.update("item", { id: 3, price: 4, name: "ruler" })
113
+ let result_7 = await db.updateOnlyID("item", { oldID: 7, newID: 4 })
114
+
115
+ let result_8 = await db.deleteByID("item", 5)
116
+ let result_9 = await db.deleteByMatchParams("item", { name: "pen", price: 5 })
117
+ ```
@@ -194,10 +194,10 @@ export default class GGMySQLConnector<Main> implements ClassDBInterface<Main> {
194
194
  return data
195
195
  }
196
196
 
197
- async deleteByMatchParams<T>(
198
- tableName: string,
197
+ async deleteByMatchParams<T extends keyof Main>(
198
+ tableName: T extends string ? T : string,
199
199
  params: Partial<{
200
- [K in keyof Unarray<T>]: string | number | undefined | null
200
+ [K in keyof Main[T]]: T | string | number | undefined | null
201
201
  }>
202
202
  ) {
203
203
  const columnList = await this.getColumnList(tableName)
@@ -220,7 +220,10 @@ export default class GGMySQLConnector<Main> implements ClassDBInterface<Main> {
220
220
  return result
221
221
  }
222
222
 
223
- async deleteByID(tableName: string, id: number): Promise<mysql.OkPacket> {
223
+ async deleteByID<T extends keyof Main>(
224
+ tableName: T extends string ? T : string,
225
+ id: number
226
+ ): Promise<mysql.OkPacket> {
224
227
  let result = (await this.query(`DELETE FROM ${tableName} WHERE id = ?`, [
225
228
  id,
226
229
  ])) as mysql.OkPacket
@@ -123,14 +123,14 @@ export default class ModelGenerator {
123
123
  )) as mysql.RowDataPacket[]
124
124
  return result
125
125
  }
126
- async generateModelInterface(
127
- DBType: string,
128
- model: MyModel[],
126
+ async generateModelInterface(params: {
127
+ appName: string
128
+ model: MyModel[]
129
129
  ouputDirectory: string[]
130
- ) {
130
+ }) {
131
131
  const isTableNameExistInModel = (tableName: string) => {
132
132
  if (tableName === "sessions") return true
133
- const table = model.find((row) => row.tableName === tableName)
133
+ const table = params.model.find((row) => row.tableName === tableName)
134
134
  if (table) return true
135
135
 
136
136
  return false
@@ -138,7 +138,7 @@ export default class ModelGenerator {
138
138
  const isColumnExistInModel = (tableName: string, columnName: string) => {
139
139
  if (tableName === "sessions") return true
140
140
 
141
- const table = model.find((row) => row.tableName === tableName)
141
+ const table = params.model.find((row) => row.tableName === tableName)
142
142
  if (table) {
143
143
  const column = table.columns.find(
144
144
  (row) => row.COLUMN_NAME === columnName
@@ -148,7 +148,7 @@ export default class ModelGenerator {
148
148
  return false
149
149
  }
150
150
  const getPossibleColumnValue = (tableName: string, columnName: string) => {
151
- const foundTable = model.find((row) => row.tableName === tableName)
151
+ const foundTable = params.model.find((row) => row.tableName === tableName)
152
152
  if (foundTable) {
153
153
  const foundColumn = foundTable["columns"].find(
154
154
  (row) => row.COLUMN_NAME === columnName
@@ -202,18 +202,20 @@ export default class ModelGenerator {
202
202
  // console.log(`generate interface from ${tableName}`)
203
203
  }
204
204
  }
205
- const fileName = `${DBType}_INF.ts`
206
- const code = `export default interface ${DBType}_INF { ${array.join(
207
- "\n"
208
- )} }`
205
+ const fileName = `${params.appName}_INF.ts`
206
+ const code = `export default interface ${
207
+ params.appName
208
+ }_INF { ${array.join("\n")} }`
209
209
 
210
- ouputDirectory.forEach(async (tempPath) => {
210
+ params.ouputDirectory.forEach(async (tempPath) => {
211
211
  const serverFilePath = path.join(tempPath, fileName)
212
212
  await fs.writeFileSync(serverFilePath, code)
213
213
  console.log("save to ", serverFilePath)
214
214
  })
215
215
 
216
- console.log(`generate interface ${DBType} ${chalk.bgGreen(" SUCCESS ")}`)
216
+ console.log(
217
+ `generate interface ${params.appName} ${chalk.bgGreen(" SUCCESS ")}`
218
+ )
217
219
 
218
220
  return code
219
221
  }
package/src/app_INF.ts CHANGED
@@ -1,12 +1,17 @@
1
- export default interface app_INF { item : {
2
- id: number;
3
- name: "pen" | "ruler";
4
- price: number;
5
- description: string; }
6
- user : {
7
- id: number;
8
- name: string; }
9
- test_view : {
10
- id: number;
11
- name: string;
12
- itemName: string; } }
1
+ export default interface app_INF {
2
+ item: {
3
+ id: number
4
+ name: "pen" | "ruler"
5
+ price: number
6
+ description: string
7
+ }
8
+ user: {
9
+ id: number
10
+ name: string
11
+ }
12
+ test_view: {
13
+ id: number
14
+ name: string
15
+ itemName: string
16
+ }
17
+ }
package/src/test/test.ts DELETED
@@ -1,48 +0,0 @@
1
- import { MyModel } from "../myModel"
2
-
3
- const model: MyModel[] = [
4
- {
5
- tableName: "user",
6
- columns: [
7
- {
8
- COLUMN_NAME: "id",
9
- DATA_TYPE: "int",
10
- AUTO_INCREMENT: true,
11
- },
12
- {
13
- COLUMN_NAME: "name",
14
- DATA_TYPE: "varchar(512)",
15
- },
16
- ],
17
- meaning: "",
18
- },
19
- {
20
- tableName: "item",
21
- columns: [
22
- {
23
- COLUMN_NAME: "id",
24
- DATA_TYPE: "int",
25
- AUTO_INCREMENT: true,
26
- },
27
- {
28
- COLUMN_NAME: "name",
29
- DATA_TYPE: "varchar(512)",
30
- POSSIBLE_VALUE: ["pen", "ruler"],
31
- },
32
- {
33
- COLUMN_NAME: "price",
34
- DATA_TYPE: "float",
35
- },
36
- {
37
- COLUMN_NAME: "description",
38
- DATA_TYPE: "varchar(512)",
39
- },
40
- ],
41
- meaning: "",
42
- },
43
- ]
44
-
45
- async function run() {
46
- process.exit()
47
- }
48
- run()