diff --git a/src/common/fieldTypes.js b/src/common/fieldTypes.js index a7d3399f..cbd8cbe6 100644 --- a/src/common/fieldTypes.js +++ b/src/common/fieldTypes.js @@ -41,6 +41,7 @@ export const NUMBER = [ export const FLOAT = [ 'FLOAT', + 'DECIMAL', 'DOUBLE', 'REAL', 'DOUBLE PRECISION', diff --git a/src/common/libs/mimeFromHex.js b/src/common/libs/mimeFromHex.js index 6d292de6..837b127e 100644 --- a/src/common/libs/mimeFromHex.js +++ b/src/common/libs/mimeFromHex.js @@ -23,7 +23,7 @@ export function mimeFromHex (hex) { case '425A68': return { ext: 'bz2', mime: 'application/x-bzip2' }; default: - switch (hex) { // 4 bites + switch (hex) { // 4 bytes case '89504E47': return { ext: 'png', mime: 'image/png' }; case '47494638': diff --git a/src/main/ipc-handlers/tables.js b/src/main/ipc-handlers/tables.js index 7791aa5b..79e0034f 100644 --- a/src/main/ipc-handlers/tables.js +++ b/src/main/ipc-handlers/tables.js @@ -149,7 +149,7 @@ export default (connections) => { } } } - else if ([...BIT].includes(params.type)) { + else if (BIT.includes(params.type)) { escapedParam = `b'${sqlEscaper(params.content)}'`; reload = true; } diff --git a/src/main/libs/clients/MySQLClient.js b/src/main/libs/clients/MySQLClient.js index d31e1be6..996ae7b7 100644 --- a/src/main/libs/clients/MySQLClient.js +++ b/src/main/libs/clients/MySQLClient.js @@ -101,6 +101,26 @@ export class MySQLClient extends AntaresCore { .filter(_type => _type.name === type.toUpperCase())[0]; } + _reducer (acc, curr) { + const type = typeof curr; + + switch (type) { + case 'number': + case 'string': + return [...acc, curr]; + case 'object': + if (Array.isArray(curr)) + return [...acc, ...curr]; + else { + const clausoles = []; + for (const key in curr) + clausoles.push(`\`${key}\` ${curr[key]}`); + + return clausoles; + } + } + } + /** * * @returns dbConfig @@ -496,6 +516,7 @@ export class MySQLClient extends AntaresCore { charset: field.CHARACTER_SET_NAME, collation: field.COLLATION_NAME, autoIncrement: field.EXTRA.includes('auto_increment'), + generated: field.EXTRA.toLowerCase().includes('generated'), onUpdate: field.EXTRA.toLowerCase().includes('on update') ? field.EXTRA.substr(field.EXTRA.indexOf('on update') + 9, field.EXTRA.length).trim() : '', @@ -1600,7 +1621,7 @@ export class MySQLClient extends AntaresCore { let insertRaw = ''; if (this._query.insert.length) { - const fieldsList = Object.keys(this._query.insert[0]); + const fieldsList = Object.keys(this._query.insert[0]).map(col => '`' + col + '`'); const rowsList = this._query.insert.map(el => `(${Object.values(el).join(', ')})`); insertRaw = `(${fieldsList.join(', ')}) VALUES ${rowsList.join(', ')} `; diff --git a/src/main/libs/exporters/sql/MysqlExporter.js b/src/main/libs/exporters/sql/MysqlExporter.js index 1af55c49..1f7526c9 100644 --- a/src/main/libs/exporters/sql/MysqlExporter.js +++ b/src/main/libs/exporters/sql/MysqlExporter.js @@ -1,6 +1,7 @@ import { SqlExporter } from './SqlExporter'; -import { BLOB, BIT } from 'common/fieldTypes'; +import { BLOB, BIT, DATE, DATETIME, FLOAT } from 'common/fieldTypes'; import hexToBinary from 'common/libs/hexToBinary'; +import moment from 'moment'; export default class MysqlExporter extends SqlExporter { async getSqlHeader () { @@ -65,7 +66,9 @@ ${footer} table: tableName, schema: this.schemaName }); - const columnNames = columns.map(col => '`' + col.name + '`'); + + const notGeneratedColumns = columns.filter(col => !col.generated); + const columnNames = notGeneratedColumns.map(col => '`' + col.name + '`'); const insertStmt = `INSERT INTO \`${tableName}\` (${columnNames.join( ', ' )}) VALUES`; @@ -101,25 +104,44 @@ ${footer} else if (parseInt(rowIndex) === 0) sqlInsertString += '\n\t('; else sqlInsertString += ',\n\t('; - for (const i in columns) { - const column = columns[i]; + for (const i in notGeneratedColumns) { + const column = notGeneratedColumns[i]; const val = row[column.name]; if (val === null) sqlInsertString += 'NULL'; + else if (DATE.includes(column.type)) { + sqlInsertString += moment(val).isValid() + ? this.escapeAndQuote(moment(val).format('YYYY-MM-DD')) + : val; + } + else if (DATETIME.includes(column.type)) { + if (typeof val === 'string') + sqlInsertString += this.escapeAndQuote(val); + + let datePrecision = ''; + for (let i = 0; i < column.precision; i++) + datePrecision += i === 0 ? '.S' : 'S'; + + sqlInsertString += moment(val).isValid() + ? this.escapeAndQuote(moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`)) + : val; + } else if (BIT.includes(column.type)) sqlInsertString += `b'${hexToBinary(Buffer.from(val).toString('hex'))}'`; - else if (BLOB.includes(column.type)) sqlInsertString += `X'${val.toString('hex').toUpperCase()}'`; - + else if (FLOAT.includes(column.type)) + sqlInsertString += parseFloat(val); else if (val === '') sqlInsertString += '\'\''; else { sqlInsertString += typeof val === 'string' ? this.escapeAndQuote(val) - : val; + : typeof val === 'object' + ? this.escapeAndQuote(JSON.stringify(val)) + : val; } - if (parseInt(i) !== columns.length - 1) + if (parseInt(i) !== notGeneratedColumns.length - 1) sqlInsertString += ', '; } @@ -302,7 +324,7 @@ ${footer} } async _queryStream (sql) { - if (process.env.NODE_ENV === 'development') console.log(sql); + if (process.env.NODE_ENV === 'development') console.log('EXPORTER:', sql); const isPool = typeof this._client._connection.getConnection === 'function'; const connection = isPool ? await this._client._connection.getConnection() : this._client._connection; const stream = connection.connection.query(sql).stream();