@verdnatura/myt 1.5.20 → 1.5.21

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
@@ -13,6 +13,11 @@ development, so any help is welcomed! Feel free to contribute.
13
13
 
14
14
  ## Installation
15
15
 
16
+ Required libraries to build with *node-gyp*.
17
+ ```text
18
+ # apt install libkrb5-dev libssl-dev
19
+ ```
20
+
16
21
  It's recommended to install the package globally.
17
22
 
18
23
  ```text
@@ -148,9 +153,10 @@ routines.
148
153
 
149
154
  You can create your local fixture and structure files.
150
155
 
151
- * *dump/beforeDump.sql*
152
- * *dump/afterDump.sql*
153
- * *dump/fixtures.sql*
156
+ * *dump/dump.before.sql*
157
+ * *dump/dump.after.sql*
158
+ * *dump/fixtures.before.sql*
159
+ * *dump/fixtures.after.sql*
154
160
 
155
161
  ## Versioning commands
156
162
 
@@ -180,7 +186,7 @@ When *--checkout* option is provided, it does the following before export:
180
186
  Applies versions and routine changes into database.
181
187
 
182
188
  ```text
183
- $ myt push [<remote>] [-f|--force] [-c|--commit] [-s|--sums]
189
+ $ myt push [<remote>] [-f|--force] [-c|--commit] [-s|--sums] [-t|--triggers]
184
190
  ```
185
191
 
186
192
  Commit is saved into database only if *--commit* option is provided, it
@@ -221,7 +227,7 @@ Exports database structure and fixtures from remote into hidden files located
221
227
  in *dump* folder. If no remote is specified *production* is used.
222
228
 
223
229
  ```text
224
- $ myt dump [<remote>] [-l|--lock]
230
+ $ myt dump [<remote>] [-l|--lock] [-t|--triggers]
225
231
  ```
226
232
 
227
233
  ### fixtures
@@ -2,7 +2,24 @@ versionSchema: myt
2
2
  versionDigits: 5
3
3
  maxOldVersions: 20
4
4
  mockDate: false
5
+ mockFunctions:
6
+ - mockTime
7
+ - mockUtcTime
5
8
  sumViews: true
9
+ privileges:
10
+ userTable: global_priv
11
+ userWhere: >-
12
+ JSON_VALUE(`Priv`, '$.is_role')
13
+ AND JSON_VALUE(`Priv`, '$.authentication_string') IS NULL
14
+ AND JSON_VALUE(`Priv`, '$.mysql_old_password') IS NULL
15
+ AND JSON_VALUE(`Priv`, '$.mysql_native_password') IS NULL
16
+ tables:
17
+ - db
18
+ - tables_priv
19
+ - columns_priv
20
+ - procs_priv
21
+ where: >-
22
+ `Host` = ''
6
23
  schemas:
7
24
  - myt
8
25
  fixtures:
@@ -0,0 +1,79 @@
1
+ #!/bin/node
2
+
3
+ require('require-yaml');
4
+ const mysql = require('mysql2/promise');
5
+ const {fixtures} = require(`${process.cwd()}/myt.config.yml`);
6
+
7
+ const config = {
8
+ host: 'localhost',
9
+ user: 'root',
10
+ password: 'root'
11
+ };
12
+
13
+ async function connectAndQuery() {
14
+ try {
15
+ const connection = await mysql.createConnection(config);
16
+
17
+ // Get schemas
18
+
19
+ const [schemaResults] = await connection.query('SHOW DATABASES');
20
+ const schemaNames = schemaResults.map(r => r.Database);
21
+
22
+ // Filter system schemas
23
+
24
+ const systemSchemas = ['mysql', 'sys', 'information_schema', 'performance_schema'];
25
+ const userSchemas = schemaNames.filter(s => !systemSchemas.includes(s));
26
+
27
+ if (userSchemas.length === 0) {
28
+ console.log('There are no user schemas with tables that have records.');
29
+ connection.end();
30
+ return;
31
+ }
32
+
33
+ // Get tables with records
34
+
35
+ userSchemas.sort((a, b) => a.localeCompare(b));
36
+ for (const schemaName of userSchemas) {
37
+ const [tableResults] = await connection.query(
38
+ `SELECT TABLE_NAME tableName
39
+ FROM information_schema.TABLES
40
+ WHERE TABLE_SCHEMA = ?
41
+ AND TABLE_TYPE <> 'VIEW'`,
42
+ [schemaName]
43
+ );
44
+ const tableNames = tableResults.map(r => r.tableName);
45
+ if (tableNames.length === 0) continue;
46
+
47
+ const schemaFixtures = new Set(fixtures[schemaName]);
48
+ const nonEmptyTables = [];
49
+
50
+ for (const tableName of tableNames) {
51
+ if (schemaFixtures.has(tableName)) continue;
52
+ try {
53
+ const [[row]] = await connection.query(
54
+ `SELECT COUNT(*) \`count\` FROM ??.??`,
55
+ [schemaName, tableName]
56
+ );
57
+ if (row.count == 0) continue;
58
+ if (!fixtures[schemaName]?.[tableName])
59
+ nonEmptyTables.push(tableName);
60
+ } catch (err) {
61
+ console.error('Error:', err.message);
62
+ }
63
+ }
64
+
65
+ nonEmptyTables.sort((a, b) => a.localeCompare(b));
66
+ if (nonEmptyTables.length) {
67
+ console.log(`${schemaName}:`);
68
+ for (const tableName of nonEmptyTables)
69
+ console.log(` - ${tableName}`);
70
+ }
71
+ }
72
+
73
+ connection.end();
74
+ } catch (err) {
75
+ console.error('Error:', err.message);
76
+ }
77
+ }
78
+
79
+ connectAndQuery();
package/lib/command.js CHANGED
@@ -10,4 +10,10 @@ module.exports = class MytCommand {
10
10
  async run(myt, opts) {
11
11
  throw new Error('run command not defined');
12
12
  }
13
+
14
+ emit(event) {
15
+ const messages = this.constructor.messages;
16
+ if (messages && messages[event])
17
+ console.log(messages[event]);
18
+ }
13
19
  }
package/lib/dumper.js CHANGED
@@ -8,12 +8,11 @@ module.exports = class Dumper {
8
8
  this.opts = opts;
9
9
  }
10
10
 
11
- async init(dumpFile) {
12
- const dumpDir = this.opts.dumpDir;
11
+ async init(dumpDir, dumpFile) {
13
12
  if (!await fs.pathExists(dumpDir))
14
- await fs.mkdir(dumpDir);
13
+ await fs.mkdir(dumpDir, {recursive: true});
15
14
 
16
- const dumpPath = path.join(dumpDir, dumpFile);
15
+ const dumpPath = path.join(dumpDir, `${dumpFile}.sql`);
17
16
 
18
17
  // FIXME: If it's called after docker.build() statement it creates an
19
18
  // "invalid" WriteStream
@@ -28,6 +27,10 @@ module.exports = class Dumper {
28
27
  this.dumpStream = dumpStream;
29
28
  }
30
29
 
30
+ async end() {
31
+ await this.dumpStream.end();
32
+ }
33
+
31
34
  async use(schema) {
32
35
  await this.dumpStream.write(
33
36
  `USE ${SqlString.escapeId(schema, true)};\n`,
@@ -36,7 +39,7 @@ module.exports = class Dumper {
36
39
  }
37
40
 
38
41
  async dumpFixtures(tables, replace, args) {
39
- const fixturesArgs = [
42
+ let fixturesArgs = [
40
43
  '--no-create-info',
41
44
  '--skip-triggers',
42
45
  '--skip-extended-insert',
@@ -45,18 +48,40 @@ module.exports = class Dumper {
45
48
  '--skip-set-charset',
46
49
  '--skip-comments',
47
50
  '--skip-tz-utc'
48
- ].concat(args);
49
-
51
+ ]
52
+ if (args)
53
+ fixturesArgs = fixturesArgs.concat(args);
50
54
  if (replace)
51
55
  fixturesArgs.push('--replace');
52
56
 
53
57
  for (const schema in tables) {
54
- await this.use(schema);
55
58
  const args = fixturesArgs.concat([schema], tables[schema]);
56
- await this.runDump('mysqldump', args, this.dumpStream);
59
+ await this.use(schema);
60
+ await this.runDump('mysqldump', args);
57
61
  }
58
62
  }
59
63
 
64
+ async dumpPrivileges(tables, args, where) {
65
+ let privArgs = [
66
+ '--no-create-info',
67
+ '--skip-triggers',
68
+ '--insert-ignore',
69
+ '--skip-extended-insert',
70
+ '--skip-add-locks',
71
+ '--skip-set-charset',
72
+ '--skip-comments',
73
+ '--skip-tz-utc'
74
+ ];
75
+ if (args)
76
+ privArgs = privArgs.concat(args);
77
+ if (where)
78
+ privArgs.push('--where', where);
79
+ args = privArgs.concat(['mysql'], tables);
80
+
81
+ await this.use('mysql');
82
+ await this.runDump('mysqldump', args);
83
+ }
84
+
60
85
  async runDump(command, args) {
61
86
  const iniPath = path.join(this.opts.subdir || '', 'remotes', this.opts.iniFile);
62
87
  const myArgs = [
@@ -76,8 +101,4 @@ module.exports = class Dumper {
76
101
  rm: true
77
102
  }, execOptions);
78
103
  }
79
-
80
- async end() {
81
- await this.dumpStream.end();
82
- }
83
104
  }
package/myt-dump.js CHANGED
@@ -1,13 +1,15 @@
1
1
  const Myt = require('./myt');
2
2
  const Command = require('./lib/command');
3
- const fs = require('fs-extra');
4
3
  const Dumper = require('./lib/dumper');
4
+ const fs = require('fs-extra');
5
+ const path = require('path');
5
6
 
6
7
  class Dump extends Command {
7
8
  static usage = {
8
9
  description: 'Dumps structure and fixtures from remote',
9
10
  params: {
10
- lock: 'Whether to lock tables on dump'
11
+ lock: 'Whether to lock tables on dump',
12
+ triggers: 'Wether to include triggers into dump'
11
13
  },
12
14
  operand: 'remote'
13
15
  };
@@ -17,54 +19,111 @@ class Dump extends Command {
17
19
  remote: 'production'
18
20
  },
19
21
  alias: {
20
- lock: 'l'
22
+ lock: 'l',
23
+ triggers: 't'
21
24
  },
22
25
  boolean: [
23
- 'lock'
26
+ 'lock',
27
+ 'triggers'
24
28
  ]
25
29
  };
26
30
 
31
+ static messages = {
32
+ dumpStructure: 'Dumping structure.',
33
+ dumpData: 'Dumping data.',
34
+ dumpPrivileges: 'Dumping privileges.',
35
+ dumpTriggers: 'Dumping triggers.'
36
+ };
37
+
27
38
  async run(myt, opts) {
28
- const dumper = new Dumper(opts);
29
- await dumper.init('.dump.sql');
39
+ let dumper;
40
+ const dumpDataDir = path.join(opts.dumpDir, '.dump');
30
41
  const baseArgs = [
31
42
  `--lock-tables=${opts.lock ? 'true' : 'false'}`
32
43
  ];
33
44
 
34
- console.log('Dumping structure.');
45
+ await fs.remove(dumpDataDir);
46
+
47
+ // Structure
48
+
49
+ this.emit('dumpStructure');
50
+
51
+ dumper = new Dumper(opts);
52
+ await dumper.init(dumpDataDir, 'structure');
35
53
  let dumpArgs = [
36
54
  '--default-character-set=utf8',
37
55
  '--no-data',
38
56
  '--comments',
39
57
  '--routines',
40
58
  '--events',
41
- '--skip-triggers',
42
- '--databases'
59
+ '--skip-triggers'
43
60
  ].concat(baseArgs);
44
61
 
62
+ dumpArgs.push('--databases');
45
63
  dumpArgs = dumpArgs.concat(opts.schemas);
46
64
  await dumper.runDump('docker-dump.sh', dumpArgs);
65
+ await dumper.end();
66
+
67
+ // Data
68
+
69
+ this.emit('dumpData');
47
70
 
48
- console.log('Dumping fixtures.');
71
+ dumper = new Dumper(opts);
72
+ await dumper.init(dumpDataDir, 'data');
49
73
  await dumper.dumpFixtures(opts.fixtures, false, baseArgs);
74
+ await dumper.end();
75
+
76
+ // Privileges
50
77
 
51
- console.log('Dumping privileges.');
52
78
  const privs = opts.privileges;
53
- if (privs && Array.isArray(privs.tables)) {
54
- let args = [
55
- '--no-create-info',
56
- '--skip-triggers',
57
- '--insert-ignore',
58
- '--complete-insert'
59
- ].concat(baseArgs);
60
- if (privs.where) args.push('--where', privs.where);
61
- args = args.concat(['mysql'], privs.tables);
79
+ if (privs) {
80
+ this.emit('dumpPrivileges');
81
+
82
+ dumper = new Dumper(opts);
83
+ await dumper.init(dumpDataDir, 'privileges');
84
+
85
+ const {tables, userTable, where} = privs;
86
+
87
+ if (tables)
88
+ await dumper.dumpPrivileges(tables, baseArgs, where);
62
89
 
63
- await dumper.use('mysql');
64
- await dumper.runDump('mysqldump', args);
90
+ if (userTable) {
91
+ let userWhere = '';
92
+ for (const cond of [where, privs.userWhere]) {
93
+ if (!cond) continue;
94
+ if (userWhere) userWhere += ' AND ';
95
+ userWhere += cond;
96
+ }
97
+ await dumper.dumpPrivileges([userTable], baseArgs, userWhere);
98
+ }
99
+
100
+ await dumper.end();
65
101
  }
66
102
 
67
103
  await dumper.end();
104
+
105
+ // Triggers
106
+
107
+ if (opts.triggers) {
108
+ this.emit('dumpTriggers');
109
+
110
+ const dumper = new Dumper(opts);
111
+ await dumper.init(dumpDataDir, 'triggers');
112
+
113
+ let dumpArgs = [
114
+ '--default-character-set=utf8',
115
+ '--no-create-info',
116
+ '--no-data',
117
+ '--no-create-db',
118
+ '--skip-opt',
119
+ '--comments'
120
+ ].concat(baseArgs);
121
+
122
+ dumpArgs.push('--databases');
123
+ dumpArgs = dumpArgs.concat(opts.schemas);
124
+ await dumper.runDump('mysqldump', dumpArgs);
125
+ await dumper.end();
126
+ }
68
127
  }
69
128
  }
70
129
 
package/myt-fixtures.js CHANGED
@@ -16,8 +16,8 @@ class Fixtures extends Command {
16
16
 
17
17
  async run(myt, opts) {
18
18
  const dumper = new Dumper(opts);
19
- await dumper.init('fixtures.sql');
20
- await dumper.dumpFixtures(opts.localFixtures, true);
19
+ await dumper.init(opts.dumpDir, '.fixtures');
20
+ await dumper.dumpFixtures(opts.localFixtures, false);
21
21
  await dumper.end();
22
22
  }
23
23
  }
@@ -26,4 +26,3 @@ module.exports = Fixtures;
26
26
 
27
27
  if (require.main === module)
28
28
  new Myt().run(Fixtures);
29
-
package/myt-pull.js CHANGED
@@ -98,7 +98,7 @@ class Pull extends Command {
98
98
  const schemas = await fs.readdir(routinesDir);
99
99
  for (const schema of schemas) {
100
100
  if (opts.schemas.indexOf(schema) == -1)
101
- await fs.remove(`${routinesDir}/${schema}`, {recursive: true});
101
+ await fs.remove(`${routinesDir}/${schema}`);
102
102
  }
103
103
 
104
104
  for (const schema in shaSums) {
package/myt-push.js CHANGED
@@ -311,7 +311,7 @@ class Push extends Command {
311
311
 
312
312
  for (const change of changes)
313
313
  try {
314
- if (opts.trigger && change.type.name === 'TRIGGER')
314
+ if (opts.triggers && change.type.name === 'TRIGGER')
315
315
  continue;
316
316
 
317
317
  const schema = change.schema;
@@ -325,7 +325,14 @@ class Push extends Command {
325
325
  newSql = await fs.readFile(fullPath, 'utf8');
326
326
  const oldSql = await engine.fetchRoutine(type, schema, name);
327
327
  const oldSum = engine.getShaSum(type, schema, name);
328
- const isEqual = newSql == oldSql;
328
+
329
+ const isMockFn = type == 'function'
330
+ && schema == opts.versionSchema
331
+ && opts.remote == 'local'
332
+ && opts.mockDate
333
+ && opts.mockFunctions
334
+ && opts.mockFunctions.indexOf(name) !== -1;
335
+ const ignore = newSql == oldSql || isMockFn;
329
336
 
330
337
  let statusMsg;
331
338
  if (exists && !oldSql)
@@ -336,7 +343,7 @@ class Push extends Command {
336
343
  statusMsg = '[·]'.yellow;
337
344
 
338
345
  let actionMsg;
339
- if (isEqual)
346
+ if (ignore)
340
347
  actionMsg = '[I]'.blue;
341
348
  else
342
349
  actionMsg = '[A]'.green;
@@ -348,7 +355,7 @@ class Push extends Command {
348
355
  change.fullName
349
356
  );
350
357
 
351
- if (!isEqual) {
358
+ if (!ignore) {
352
359
  const scapedSchema = SqlString.escapeId(schema, true);
353
360
 
354
361
  if (exists) {
package/myt-run.js CHANGED
@@ -36,9 +36,10 @@ class Run extends Command {
36
36
 
37
37
  async run(myt, opts) {
38
38
  const dumpDir = opts.dumpDir;
39
+ const dumpDataDir = path.join(dumpDir, '.dump');
39
40
  const serverDir = path.join(__dirname, 'server');
40
41
 
41
- if (!await fs.pathExists(`${dumpDir}/.dump.sql`))
42
+ if (!await fs.pathExists(`${dumpDataDir}/structure.sql`))
42
43
  throw new Error('To run local database you have to create a dump first');
43
44
 
44
45
  // Build base image
@@ -118,12 +119,29 @@ class Run extends Command {
118
119
  }
119
120
 
120
121
  await server.wait();
122
+ const conn = await myt.createConnection();
123
+
124
+ // Mock date functions
125
+
126
+ console.log('Mocking date functions.');
127
+ const mockDateScript = path.join(dumpDir, 'mockDate.sql');
128
+
129
+ if (opts.mockDate) {
130
+ if (!await fs.pathExists(mockDateScript))
131
+ throw new Error(`Date mock enabled but mock script does not exist: ${mockDateScript}`);
132
+
133
+ let sql = await fs.readFile(mockDateScript, 'utf8');
134
+ sql = sql.replace(/@mockDate/g, SqlString.escape(opts.mockDate));
135
+ await connExt.multiQuery(conn, sql);
136
+ }
121
137
 
122
138
  // Apply changes
123
139
 
140
+ const hasTriggers = await fs.exists(`${dumpDataDir}/triggers.sql`);
141
+
124
142
  Object.assign(opts, {
143
+ triggers: hasTriggers,
125
144
  commit: true,
126
- trigger: true,
127
145
  dbConfig
128
146
  });
129
147
  await myt.runCommand(Push, opts);
@@ -131,40 +149,35 @@ class Run extends Command {
131
149
  // Apply fixtures
132
150
 
133
151
  console.log('Applying fixtures.');
134
- await ct.exec(null,
135
- 'docker-import.sh',
136
- ['/workspace/dump/fixtures'],
137
- 'spawn',
138
- true
139
- );
140
-
141
- // Create triggers
142
-
143
- console.log('Creating triggers.');
144
- const conn = await myt.createConnection();
145
-
146
- for (const schema of opts.schemas) {
147
- const triggersPath = `${opts.routinesDir}/${schema}/triggers`;
148
- if (!await fs.pathExists(triggersPath))
149
- continue;
150
-
151
- const triggersDir = await fs.readdir(triggersPath);
152
- for (const triggerFile of triggersDir)
153
- await connExt.queryFromFile(conn, `${triggersPath}/${triggerFile}`);
152
+ const fixturesFiles = [
153
+ 'fixtures.before',
154
+ '.fixtures',
155
+ 'fixtures.after',
156
+ 'fixtures.local'
157
+ ]
158
+ for (const file of fixturesFiles) {
159
+ if (!await fs.exists(`${dumpDir}/${file}.sql`)) continue;
160
+ await ct.exec(null, 'docker-import.sh',
161
+ [`/workspace/dump/${file}`],
162
+ 'spawn',
163
+ true
164
+ );
154
165
  }
155
166
 
156
- // Mock date functions
167
+ // Create triggers
157
168
 
158
- console.log('Mocking date functions.');
159
- const mockDateScript = path.join(dumpDir, 'mockDate.sql');
169
+ if (!hasTriggers) {
170
+ console.log('Creating triggers.');
160
171
 
161
- if (opts.mockDate) {
162
- if (!await fs.pathExists(mockDateScript))
163
- throw new Error(`Date mock enabled but mock script does not exist: ${mockDateScript}`);
172
+ for (const schema of opts.schemas) {
173
+ const triggersPath = `${opts.routinesDir}/${schema}/triggers`;
174
+ if (!await fs.pathExists(triggersPath))
175
+ continue;
164
176
 
165
- let sql = await fs.readFile(mockDateScript, 'utf8');
166
- sql = sql.replace(/@mockDate/g, SqlString.escape(opts.mockDate));
167
- await connExt.multiQuery(conn, sql);
177
+ const triggersDir = await fs.readdir(triggersPath);
178
+ for (const triggerFile of triggersDir)
179
+ await connExt.queryFromFile(conn, `${triggersPath}/${triggerFile}`);
180
+ }
168
181
  }
169
182
 
170
183
  return server;
package/myt-version.js CHANGED
@@ -123,7 +123,7 @@ class Version extends Command {
123
123
  } catch (err) {
124
124
  await conn.query('ROLLBACK');
125
125
  if (newVersionDir && await fs.pathExists(newVersionDir))
126
- await fs.remove(newVersionDir, {recursive: true});
126
+ await fs.remove(newVersionDir);
127
127
  throw err;
128
128
  }
129
129
  }
package/myt.js CHANGED
@@ -170,12 +170,29 @@ class Myt {
170
170
  async load(opts) {
171
171
  // Configuration file
172
172
 
173
- const config = require(`${__dirname}/assets/myt.default.yml`);
173
+ const defaultConfig = require(`${__dirname}/assets/myt.default.yml`);
174
+ const config = Object.assign({}, defaultConfig);
174
175
 
175
176
  const configFile = 'myt.config.yml';
176
177
  const configPath = path.join(opts.workspace, configFile);
177
- if (await fs.pathExists(configPath))
178
- Object.assign(config, require(configPath));
178
+
179
+ if (await fs.pathExists(configPath)) {
180
+ const mergeKeys = new Set([
181
+ 'privileges'
182
+ ]);
183
+
184
+ const wsConfig = require(configPath);
185
+ for (const key in wsConfig) {
186
+ if (!mergeKeys.has(key)) {
187
+ config[key] = wsConfig[key];
188
+ } else {
189
+ config[key] = Object.assign({},
190
+ config[key],
191
+ wsConfig[key]
192
+ );
193
+ }
194
+ }
195
+ }
179
196
 
180
197
  Object.assign(opts, config);
181
198
  opts.configFile = configFile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdnatura/myt",
3
- "version": "1.5.20",
3
+ "version": "1.5.21",
4
4
  "author": "Verdnatura Levante SL",
5
5
  "description": "MySQL version control",
6
6
  "license": "GPL-3.0",
@@ -15,10 +15,10 @@
15
15
  "@sqltools/formatter": "^1.2.5",
16
16
  "colors": "^1.4.0",
17
17
  "ejs": "^3.1.9",
18
- "fs-extra": "^8.1.0",
18
+ "fs-extra": "^11.1.1",
19
19
  "getopts": "^2.3.0",
20
- "ini": "^1.3.8",
21
- "mysql2": "^2.3.3",
20
+ "ini": "^4.1.1",
21
+ "mysql2": "^3.3.4",
22
22
  "nodegit": "^0.27.0",
23
23
  "require-yaml": "^0.0.1",
24
24
  "sha.js": "^2.4.11"
@@ -2,11 +2,8 @@ FROM myt/server
2
2
 
3
3
  USER root
4
4
 
5
- COPY \
6
- .dump.sql \
7
- beforeDump.sql \
8
- afterDump.sql \
9
- dump/
5
+ COPY .dump dump/.dump
6
+ COPY dump.*.sql dump/
10
7
 
11
8
  RUN gosu mysql docker-init.sh
12
9
 
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
2
 
3
3
  # FIXME: It can corrupt data
4
+ # Currently not used, instead mysqldump --skip-extended-insert option is used
4
5
  mysqldump $@ | sed -E 's/(VALUES |\),)\(/\1\n\t\(/g'
@@ -1,6 +1,10 @@
1
1
  #!/bin/bash
2
2
 
3
3
  FILE="$1.sql"
4
+ if [[ ! -f "$FILE" ]] ; then
5
+ exit
6
+ fi
7
+
4
8
  echo "[LOG] -> Importing $FILE"
5
9
  export MYSQL_PWD=root
6
10
  mysql -u root --default-character-set=utf8 --comments -f < "$FILE"
@@ -13,8 +13,11 @@ docker_temp_server_start "$CMD"
13
13
  docker_setup_db
14
14
  docker_process_init_files /docker-entrypoint-initdb.d/*
15
15
 
16
- docker-import.sh dump/beforeDump
17
- docker-import.sh dump/.dump
18
- docker-import.sh dump/afterDump
16
+ docker-import.sh dump/dump.before
17
+ docker-import.sh dump/.dump/structure
18
+ docker-import.sh dump/.dump/data
19
+ docker-import.sh dump/.dump/triggers
20
+ docker-import.sh dump/.dump/privileges
21
+ docker-import.sh dump/dump.after
19
22
 
20
23
  docker_temp_server_stop
@@ -0,0 +1 @@
1
+ -- Executed after dump
@@ -0,0 +1 @@
1
+ -- Executed before dump
@@ -0,0 +1 @@
1
+ -- Executed after fixtures
@@ -0,0 +1 @@
1
+ -- Executed before fixtures
@@ -1 +0,0 @@
1
- -- Executed after data dump
@@ -1 +0,0 @@
1
- -- Executed before data dump
@@ -1 +0,0 @@
1
- -- Place your local fixtures here