mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
fix(PostgreSQL): wrong values exporting table content
This commit is contained in:
@ -39,6 +39,7 @@ module.exports = {
|
|||||||
schemaEdit: false,
|
schemaEdit: false,
|
||||||
schemaDrop: false,
|
schemaDrop: false,
|
||||||
schemaExport: false,
|
schemaExport: false,
|
||||||
|
exportByChunks: false,
|
||||||
schemaImport: false,
|
schemaImport: false,
|
||||||
tableSettings: false,
|
tableSettings: false,
|
||||||
tableOptions: false,
|
tableOptions: false,
|
||||||
|
@ -35,6 +35,7 @@ module.exports = {
|
|||||||
schemaEdit: true,
|
schemaEdit: true,
|
||||||
schemaDrop: true,
|
schemaDrop: true,
|
||||||
schemaExport: true,
|
schemaExport: true,
|
||||||
|
exportByChunks: true,
|
||||||
schemaImport: true,
|
schemaImport: true,
|
||||||
tableSettings: true,
|
tableSettings: true,
|
||||||
viewSettings: true,
|
viewSettings: true,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SqlExporter } from './SqlExporter';
|
import { SqlExporter } from './SqlExporter';
|
||||||
import { BLOB, BIT, DATE, DATETIME, FLOAT, SPATIAL, IS_MULTI_SPATIAL, NUMBER } from 'common/fieldTypes';
|
import { BLOB, BIT, DATE, DATETIME, FLOAT, NUMBER, TEXT_SEARCH } from 'common/fieldTypes';
|
||||||
import hexToBinary from 'common/libs/hexToBinary';
|
import hexToBinary from 'common/libs/hexToBinary';
|
||||||
import { getArrayDepth } from 'common/libs/getArrayDepth';
|
import { getArrayDepth } from 'common/libs/getArrayDepth';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -17,12 +17,14 @@ SET lock_timeout = 0;
|
|||||||
SET idle_in_transaction_session_timeout = 0;
|
SET idle_in_transaction_session_timeout = 0;
|
||||||
SET client_encoding = 'UTF8';
|
SET client_encoding = 'UTF8';
|
||||||
SET standard_conforming_strings = on;
|
SET standard_conforming_strings = on;
|
||||||
-- SELECT pg_catalog.set_config('search_path', '', false);
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
SET check_function_bodies = false;
|
SET check_function_bodies = false;
|
||||||
SET xmloption = content;
|
SET xmloption = content;
|
||||||
SET client_min_messages = warning;
|
SET client_min_messages = warning;
|
||||||
SET row_security = off;\n\n\n`;
|
SET row_security = off;\n\n\n`;
|
||||||
|
|
||||||
|
if (this.schemaName !== 'public') dump += `CREATE SCHEMA "${this.schemaName}";\n\n`;
|
||||||
|
|
||||||
dump += await this.getCreateTypes();
|
dump += await this.getCreateTypes();
|
||||||
|
|
||||||
return dump;
|
return dump;
|
||||||
@ -43,19 +45,19 @@ SET row_security = off;\n\n\n`;
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Table columns
|
// Table columns
|
||||||
const { rows } = await this._client
|
const { rows } = await this._client.raw(`
|
||||||
.select('*')
|
SELECT *
|
||||||
.schema('information_schema')
|
FROM "information_schema"."columns"
|
||||||
.from('columns')
|
WHERE "table_schema" = '${this.schemaName}'
|
||||||
.where({ table_schema: `= '${this.schemaName}'`, table_name: `= '${tableName}'` })
|
AND "table_name" = '${tableName}'
|
||||||
.orderBy({ ordinal_position: 'ASC' })
|
ORDER BY "ordinal_position" ASC
|
||||||
.run();
|
`, { schema: 'information_schema' });
|
||||||
|
|
||||||
if (!rows.length) return '';
|
if (!rows.length) return '';
|
||||||
|
|
||||||
for (const column of rows) {
|
for (const column of rows) {
|
||||||
let fieldType = column.data_type;
|
let fieldType = column.data_type;
|
||||||
if (fieldType === 'USER-DEFINED') fieldType = column.udt_name;
|
if (fieldType === 'USER-DEFINED') fieldType = `"${this.schemaName}".${column.udt_name}`;
|
||||||
else if (fieldType === 'ARRAY') {
|
else if (fieldType === 'ARRAY') {
|
||||||
if (Object.keys(arrayTypes).includes(fieldType))
|
if (Object.keys(arrayTypes).includes(fieldType))
|
||||||
fieldType = arrayTypes[type] + '[]';
|
fieldType = arrayTypes[type] + '[]';
|
||||||
@ -71,8 +73,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
if (column.column_default) {
|
if (column.column_default) {
|
||||||
columnArr.push(`DEFAULT ${column.column_default}`);
|
columnArr.push(`DEFAULT ${column.column_default}`);
|
||||||
if (column.column_default.includes('nextval')) {
|
if (column.column_default.includes('nextval')) {
|
||||||
let sequenceName = column.column_default.split('\'')[1];
|
const sequenceName = column.column_default.split('\'')[1];
|
||||||
if (sequenceName.includes('.')) sequenceName = sequenceName.split('.')[1];
|
|
||||||
sequences.push(sequenceName);
|
sequences.push(sequenceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +83,9 @@ SET row_security = off;\n\n\n`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Table sequences
|
// Table sequences
|
||||||
for (const sequence of sequences) {
|
for (let sequence of sequences) {
|
||||||
|
if (sequence.includes('.')) sequence = sequence.split('.')[1];
|
||||||
|
|
||||||
const { rows } = await this._client
|
const { rows } = await this._client
|
||||||
.select('*')
|
.select('*')
|
||||||
.schema('information_schema')
|
.schema('information_schema')
|
||||||
@ -91,7 +94,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
.run();
|
.run();
|
||||||
|
|
||||||
if (rows.length) {
|
if (rows.length) {
|
||||||
createSql += `CREATE SEQUENCE "${sequence}"
|
createSql += `CREATE SEQUENCE "${this.schemaName}"."${sequence}"
|
||||||
START WITH ${rows[0].start_value}
|
START WITH ${rows[0].start_value}
|
||||||
INCREMENT BY ${rows[0].increment}
|
INCREMENT BY ${rows[0].increment}
|
||||||
MINVALUE ${rows[0].minimum_value}
|
MINVALUE ${rows[0].minimum_value}
|
||||||
@ -103,7 +106,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Table create
|
// Table create
|
||||||
createSql += `\nCREATE TABLE "${tableName}"(
|
createSql += `\nCREATE TABLE "${this.schemaName}"."${tableName}"(
|
||||||
${columnsSql.join(',\n ')}
|
${columnsSql.join(',\n ')}
|
||||||
);\n`;
|
);\n`;
|
||||||
|
|
||||||
@ -119,7 +122,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
.run();
|
.run();
|
||||||
|
|
||||||
for (const index of indexes)
|
for (const index of indexes)
|
||||||
createSql += `${index.indexdef.replaceAll(`${this.schemaName}.`, '')};\n`;
|
createSql += `${index.indexdef};\n`;
|
||||||
|
|
||||||
// Table foreigns
|
// Table foreigns
|
||||||
const { rows: foreigns } = await this._client.raw(`
|
const { rows: foreigns } = await this._client.raw(`
|
||||||
@ -147,15 +150,15 @@ SET row_security = off;\n\n\n`;
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
for (const foreign of foreigns) {
|
for (const foreign of foreigns) {
|
||||||
this._postTablesSql += `\nALTER TABLE ONLY "${tableName}"
|
this._postTablesSql += `\nALTER TABLE ONLY "${this.schemaName}"."${tableName}"
|
||||||
ADD CONSTRAINT "${foreign.constraint_name}" FOREIGN KEY ("${foreign.column_name}") REFERENCES "${foreign.foreign_table_name}" ("${foreign.foreign_column_name}") ON UPDATE ${foreign.update_rule} ON DELETE ${foreign.delete_rule};\n`;
|
ADD CONSTRAINT "${foreign.constraint_name}" FOREIGN KEY ("${foreign.column_name}") REFERENCES "${this.schemaName}"."${foreign.foreign_table_name}" ("${foreign.foreign_column_name}") ON UPDATE ${foreign.update_rule} ON DELETE ${foreign.delete_rule};\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSql;
|
return createSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDropTable (tableName) {
|
getDropTable (tableName) {
|
||||||
return `DROP TABLE IF EXISTS "${tableName}";`;
|
return `DROP TABLE IF EXISTS "${this.schemaName}"."${tableName}";`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async * getTableInsert (tableName) {
|
async * getTableInsert (tableName) {
|
||||||
@ -166,16 +169,12 @@ SET row_security = off;\n\n\n`;
|
|||||||
if (countResults.rows.length === 1) rowCount = countResults.rows[0].count;
|
if (countResults.rows.length === 1) rowCount = countResults.rows[0].count;
|
||||||
|
|
||||||
if (rowCount > 0) {
|
if (rowCount > 0) {
|
||||||
let queryLength = 0;
|
|
||||||
let rowsWritten = 0;
|
|
||||||
const { sqlInsertDivider, sqlInsertAfter } = this._options;
|
|
||||||
const columns = await this._client.getTableColumns({
|
const columns = await this._client.getTableColumns({
|
||||||
table: tableName,
|
table: tableName,
|
||||||
schema: this.schemaName
|
schema: this.schemaName
|
||||||
});
|
});
|
||||||
|
|
||||||
const notGeneratedColumns = columns.filter(col => !col.generated);
|
const columnNames = columns.map(col => '"' + col.name + '"').join(', ');
|
||||||
const columnNames = notGeneratedColumns.map(col => '"' + col.name + '"').join(', ');
|
|
||||||
|
|
||||||
yield sqlStr;
|
yield sqlStr;
|
||||||
|
|
||||||
@ -190,20 +189,12 @@ SET row_security = off;\n\n\n`;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sqlInsertString = `INSERT INTO "${tableName}" (${columnNames}) VALUES`;
|
let sqlInsertString = `INSERT INTO "${this.schemaName}"."${tableName}" (${columnNames}) VALUES`;
|
||||||
|
|
||||||
if (
|
|
||||||
(sqlInsertDivider === 'bytes' && queryLength >= sqlInsertAfter * 1024) ||
|
|
||||||
(sqlInsertDivider === 'rows' && rowsWritten === sqlInsertAfter)
|
|
||||||
) {
|
|
||||||
queryLength = 0;
|
|
||||||
rowsWritten = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlInsertString += ' (';
|
sqlInsertString += ' (';
|
||||||
|
|
||||||
for (const i in notGeneratedColumns) {
|
for (const i in columns) {
|
||||||
const column = notGeneratedColumns[i];
|
const column = columns[i];
|
||||||
const val = row[column.name];
|
const val = row[column.name];
|
||||||
|
|
||||||
if (val === null) sqlInsertString += 'NULL';
|
if (val === null) sqlInsertString += 'NULL';
|
||||||
@ -221,31 +212,24 @@ SET row_security = off;\n\n\n`;
|
|||||||
? this.escapeAndQuote(moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`))
|
? this.escapeAndQuote(moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`))
|
||||||
: this.escapeAndQuote(val);
|
: this.escapeAndQuote(val);
|
||||||
}
|
}
|
||||||
|
else if (column.isArray) {
|
||||||
|
let parsedVal;
|
||||||
|
if (Array.isArray(val))
|
||||||
|
parsedVal = JSON.stringify(val).replaceAll('[', '{').replaceAll(']', '}');
|
||||||
|
else
|
||||||
|
parsedVal = typeof val === 'string' ? val.replaceAll('[', '{').replaceAll(']', '}') : '';
|
||||||
|
sqlInsertString += `'${parsedVal}'`;
|
||||||
|
}
|
||||||
|
else if (TEXT_SEARCH.includes(column.type))
|
||||||
|
sqlInsertString += `'${val.replaceAll('\'', '\'\'')}'`;
|
||||||
else if (BIT.includes(column.type))
|
else if (BIT.includes(column.type))
|
||||||
sqlInsertString += `b'${hexToBinary(Buffer.from(val).toString('hex'))}'`;
|
sqlInsertString += `b'${hexToBinary(Buffer.from(val).toString('hex'))}'`;
|
||||||
else if (BLOB.includes(column.type))
|
else if (BLOB.includes(column.type))
|
||||||
sqlInsertString += `X'${val.toString('hex').toUpperCase()}'`;
|
sqlInsertString += `decode('${val.toString('hex').toUpperCase()}', 'hex')`;
|
||||||
else if (NUMBER.includes(column.type))
|
else if (NUMBER.includes(column.type))
|
||||||
sqlInsertString += val;
|
sqlInsertString += val;
|
||||||
else if (FLOAT.includes(column.type))
|
else if (FLOAT.includes(column.type))
|
||||||
sqlInsertString += parseFloat(val);
|
sqlInsertString += parseFloat(val);
|
||||||
else if (SPATIAL.includes(column.type)) {
|
|
||||||
let geoJson;
|
|
||||||
if (IS_MULTI_SPATIAL.includes(column.type)) {
|
|
||||||
const features = [];
|
|
||||||
for (const element of val)
|
|
||||||
features.push(this.getMarkers(element));
|
|
||||||
|
|
||||||
geoJson = {
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
geoJson = this._getGeoJSON(val);
|
|
||||||
|
|
||||||
sqlInsertString += `ST_GeomFromGeoJSON('${JSON.stringify(geoJson)}')`;
|
|
||||||
}
|
|
||||||
else if (val === '') sqlInsertString += '\'\'';
|
else if (val === '') sqlInsertString += '\'\'';
|
||||||
else {
|
else {
|
||||||
sqlInsertString += typeof val === 'string'
|
sqlInsertString += typeof val === 'string'
|
||||||
@ -255,14 +239,12 @@ SET row_security = off;\n\n\n`;
|
|||||||
: val;
|
: val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseInt(i) !== notGeneratedColumns.length - 1)
|
if (parseInt(i) !== columns.length - 1)
|
||||||
sqlInsertString += ', ';
|
sqlInsertString += ', ';
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlInsertString += ');\n';
|
sqlInsertString += ');\n';
|
||||||
|
|
||||||
queryLength += sqlInsertString.length;
|
|
||||||
rowsWritten++;
|
|
||||||
yield sqlInsertString;
|
yield sqlInsertString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +275,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
for (const type of typesArr) {
|
for (const type of typesArr) {
|
||||||
sqlString += `CREATE TYPE "${type.name}" AS ENUM (
|
sqlString += `CREATE TYPE "${this.schemaName}"."${type.name}" AS ENUM (
|
||||||
${type.enums.join(',\n\t')}
|
${type.enums.join(',\n\t')}
|
||||||
);`;
|
);`;
|
||||||
}
|
}
|
||||||
@ -339,7 +321,7 @@ SET row_security = off;\n\n\n`;
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (aggregateDef.length)
|
if (aggregateDef.length)
|
||||||
sqlString += '\n\n' + aggregateDef[0].format.replaceAll(`${this.schemaName}.`, '');
|
sqlString += '\n\n' + aggregateDef[0].format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,25 +335,25 @@ SET row_security = off;\n\n\n`;
|
|||||||
for (const view of views) {
|
for (const view of views) {
|
||||||
sqlString += `\nDROP VIEW IF EXISTS "${view.viewname}";\n`;
|
sqlString += `\nDROP VIEW IF EXISTS "${view.viewname}";\n`;
|
||||||
|
|
||||||
const { rows: columns } = await this._client
|
// const { rows: columns } = await this._client
|
||||||
.select('*')
|
// .select('*')
|
||||||
.schema('information_schema')
|
// .schema('information_schema')
|
||||||
.from('columns')
|
// .from('columns')
|
||||||
.where({ table_schema: `= '${this.schemaName}'`, table_name: `= '${view.viewname}'` })
|
// .where({ table_schema: `= '${this.schemaName}'`, table_name: `= '${view.viewname}'` })
|
||||||
.orderBy({ ordinal_position: 'ASC' })
|
// .orderBy({ ordinal_position: 'ASC' })
|
||||||
.run();
|
// .run();
|
||||||
|
|
||||||
sqlString += `
|
// sqlString += `
|
||||||
CREATE VIEW "${view.viewname}" AS
|
// CREATE VIEW "${this.schemaName}"."${view.viewname}" AS
|
||||||
SELECT
|
// SELECT
|
||||||
${columns.reduce((acc, curr) => {
|
// ${columns.reduce((acc, curr) => {
|
||||||
const fieldType = curr.data_type === 'USER-DEFINED' ? curr.udt_name : curr.data_type;
|
// const fieldType = curr.data_type === 'USER-DEFINED' ? curr.udt_name : curr.data_type;
|
||||||
acc.push(`NULL::${fieldType}${curr.character_maximum_length ? `(${curr.character_maximum_length})` : ''} AS "${curr.column_name}"`);
|
// acc.push(`NULL::${fieldType}${curr.character_maximum_length ? `(${curr.character_maximum_length})` : ''} AS "${curr.column_name}"`);
|
||||||
return acc;
|
// return acc;
|
||||||
}, []).join(',\n ')};
|
// }, []).join(',\n ')};
|
||||||
`;
|
// `;
|
||||||
|
|
||||||
sqlString += `\nCREATE OR REPLACE VIEW "${view.viewname}" AS \n${view.definition}\n`;
|
sqlString += `\nCREATE OR REPLACE VIEW "${this.schemaName}"."${view.viewname}" AS \n${view.definition}\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sqlString;
|
return sqlString;
|
||||||
@ -389,7 +371,7 @@ SELECT
|
|||||||
const { rows: functionDef } = await this._client.raw(
|
const { rows: functionDef } = await this._client.raw(
|
||||||
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
||||||
);
|
);
|
||||||
sqlString += `\n${functionDef[0].definition.replaceAll(`${this.schemaName}.`, '')};\n`;
|
sqlString += `\n${functionDef[0].definition};\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rows: triggers } = await this._client.raw(
|
const { rows: triggers } = await this._client.raw(
|
||||||
@ -409,7 +391,7 @@ SELECT
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
for (const trigger of remappedTriggers)
|
for (const trigger of remappedTriggers)
|
||||||
sqlString += `\nCREATE TRIGGER "${trigger.trigger_name}" ${trigger.action_timing} ${trigger.events.join(' OR ')} ON "${trigger.event_object_table}" FOR EACH ${trigger.action_orientation} ${trigger.action_statement};\n`;
|
sqlString += `\nCREATE TRIGGER "${trigger.trigger_name}" ${trigger.action_timing} ${trigger.events.join(' OR ')} ON "${this.schemaName}"."${trigger.event_object_table}" FOR EACH ${trigger.action_orientation} ${trigger.action_statement};\n`;
|
||||||
|
|
||||||
return sqlString;
|
return sqlString;
|
||||||
}
|
}
|
||||||
@ -424,7 +406,7 @@ SELECT
|
|||||||
const { rows: functionDef } = await this._client.raw(
|
const { rows: functionDef } = await this._client.raw(
|
||||||
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
||||||
);
|
);
|
||||||
sqlString += `\n${functionDef[0].definition.replaceAll(`${this.schemaName}.`, '')};\n`;
|
sqlString += `\n${functionDef[0].definition};\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlString += await this.getCreateAggregates();
|
sqlString += await this.getCreateAggregates();
|
||||||
@ -442,7 +424,7 @@ SELECT
|
|||||||
const { rows: functionDef } = await this._client.raw(
|
const { rows: functionDef } = await this._client.raw(
|
||||||
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
`SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '${func.name}')) AS definition`
|
||||||
);
|
);
|
||||||
sqlString += `\n${functionDef[0].definition.replaceAll(`${this.schemaName}.`, '')};\n`;
|
sqlString += `\n${functionDef[0].definition};\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sqlString;
|
return sqlString;
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
>
|
>
|
||||||
<input v-model="options.includes[key]" type="checkbox"><i class="form-icon" /> {{ $tc(`word.${key}`, 2) }}
|
<input v-model="options.includes[key]" type="checkbox"><i class="form-icon" /> {{ $tc(`word.${key}`, 2) }}
|
||||||
</label>
|
</label>
|
||||||
|
<div v-if="customizations.exportByChunks">
|
||||||
<div class="h6 mt-4 mb-2">
|
<div class="h6 mt-4 mb-2">
|
||||||
{{ $t('message.newInserStmtEvery') }}:
|
{{ $t('message.newInserStmtEvery') }}:
|
||||||
</div>
|
</div>
|
||||||
@ -216,6 +216,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="h6 mb-2 mt-4">
|
<div class="h6 mb-2 mt-4">
|
||||||
{{ $t('message.ourputFormat') }}:
|
{{ $t('message.ourputFormat') }}:
|
||||||
@ -306,6 +307,9 @@ export default {
|
|||||||
currentWorkspace () {
|
currentWorkspace () {
|
||||||
return this.getWorkspace(this.selectedWorkspace);
|
return this.getWorkspace(this.selectedWorkspace);
|
||||||
},
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.currentWorkspace.customizations;
|
||||||
|
},
|
||||||
schemaItems () {
|
schemaItems () {
|
||||||
const db = this.currentWorkspace.structure.find(db => db.name === this.selectedSchema);
|
const db = this.currentWorkspace.structure.find(db => db.name === this.selectedSchema);
|
||||||
if (db)
|
if (db)
|
||||||
|
Reference in New Issue
Block a user