From 07c5f64265e4f391c878fddf4adf2f50dc7acdc7 Mon Sep 17 00:00:00 2001 From: wbuezas Date: Mon, 22 Jul 2024 13:51:54 -0300 Subject: [PATCH] improvements --- src/components/common/VnForm.vue | 87 ++++++++++++---------------- src/js/db/sqlService.js | 42 ++++++++++++++ src/pages/Account/AddressDetails.vue | 4 +- 3 files changed, 80 insertions(+), 53 deletions(-) create mode 100644 src/js/db/sqlService.js diff --git a/src/components/common/VnForm.vue b/src/components/common/VnForm.vue index 02785dad..4e5447ba 100644 --- a/src/components/common/VnForm.vue +++ b/src/components/common/VnForm.vue @@ -3,6 +3,10 @@ import { ref, inject, onMounted, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import useNotify from 'src/composables/useNotify.js'; +import { + generateUpdateSqlQuery, + generateInsertSqlQuery +} from 'src/js/db/sqlService.js'; const props = defineProps({ title: { @@ -17,9 +21,11 @@ const props = defineProps({ type: String, default: '' }, + // Objeto que define las pks de la tabla. Usado para generar las queries sql correspondientes. + // Debe ser definido como un objeto de pares key-value, donde la clave es el nombre de la columna de la pk. pks: { type: Object, - default: () => {} // definidas como key: value, donde key es el nombre de la pk + default: () => {} }, createModelDefault: { type: Object, @@ -28,29 +34,33 @@ const props = defineProps({ value: '' }) }, + // Objeto que contiene la consulta SQL y los parĂ¡metros necesarios para obtener los datos iniciales del formulario. + // `query` debe ser una cadena de texto que representa la consulta SQL. + // `params` es un objeto que mapea los parĂ¡metros de la consulta a sus valores. fetchFormDataSql: { type: Object, default: () => ({ - // Objeto con query y params para obtener los datos iniciales del form query: '', params: {} }) }, + // Objeto con los datos iniciales del form, si este objeto es definido, no se ejecuta la query fetchFormDataSql formInitialData: { type: Object, - default: () => {} // Objeto con los datos iniciales del form + default: () => {} }, + // Array de columnas que no se deben actualizar columnsToIgnoreUpdate: { type: Array, - default: () => [] // Array de columnas que no se deben actualizar + default: () => [] }, autoLoad: { type: Boolean, default: true }, - mode: { - type: String, - default: 'update' + isEditMode: { + type: Boolean, + default: true }, defaultActions: { type: Boolean, @@ -73,7 +83,7 @@ const tableColumns = computed( () => modelInfo.value?.columns.map(col => col.name) || [] ); // Array de nombre de columnas que fueron actualizadas y no estan en columnsToIgnoreUpdate -const columnsUpdated = computed(() => { +const updatedColumns = computed(() => { return tableColumns.value.filter( colName => modelInfo.value?.data[0][colName] !== formData.value[colName] && @@ -106,7 +116,7 @@ const fetchFormData = async () => { const submit = async () => { try { - const sqlQuery = generateSqlQuery(props.table, props.schema, props.pks); + const sqlQuery = generateSqlQuery(); await jApi.execQuery(sqlQuery, props.pks); emit('onDataSaved'); notify(t('dataSaved'), 'positive'); @@ -116,51 +126,26 @@ const submit = async () => { } }; -const generateSqlQuery = (table, schema, pks) => { - if (props.mode === 'update') { - return generateUpdateSqlQuery(table, schema, pks); +const generateSqlQuery = () => { + if (props.isEditMode) { + return generateUpdateSqlQuery( + props.schema, + props.table, + props.pks, + updatedColumns.value, + formData.value + ); } else { - return generateCreateSqlQuery(table, schema, pks); + return generateInsertSqlQuery( + props.schema, + props.table, + formData.value, + updatedColumns.value, + props.createModelDefault + ); } }; -const generateUpdateSqlQuery = (table, schema, pks) => { - if (!columnsUpdated.value.length) return ''; - - const setClauses = columnsUpdated.value - .map(colName => `${colName} = '${formData.value[colName]}'`) - .join(', '); - const whereClause = Object.keys(props.pks) - .map(pk => `${pk} = ${pks[pk]}`) - .join(' AND '); - return ` - START TRANSACTION; - UPDATE ${schema}.${table} SET ${setClauses} WHERE (${whereClause}); - SELECT ${columnsUpdated.value.join(', ')} FROM ${schema}.${table} WHERE (${whereClause}); - COMMIT; - `; -}; - -const generateCreateSqlQuery = (table, schema) => { - if (!columnsUpdated.value.length) return ''; - - const columns = [ - props.createModelDefault.field, - ...columnsUpdated.value - ].join(', '); - const values = [ - props.createModelDefault.value, - ...columnsUpdated.value.map(colName => `'${formData.value[colName]}'`) - ].join(', '); - - return ` - START TRANSACTION; - INSERT INTO ${schema}.${table} (${columns}) VALUES (${values}); - SELECT id, ${columnsUpdated.value.join(', ')} FROM ${schema}.${table} WHERE ((id = LAST_INSERT_ID())); - COMMIT; - `; -}; - onMounted(async () => { if (!props.formInitialData && props.autoLoad) { fetchFormData(); @@ -182,7 +167,7 @@ defineExpose({ icon="check" rounded no-caps - :disabled="!columnsUpdated.length" + :disabled="!updatedColumns.length" @click="addressFormRef.submit()" /> diff --git a/src/js/db/sqlService.js b/src/js/db/sqlService.js new file mode 100644 index 00000000..375e2f74 --- /dev/null +++ b/src/js/db/sqlService.js @@ -0,0 +1,42 @@ +export const generateUpdateSqlQuery = ( + schema, + table, + pks, + columnsUpdated, + formData +) => { + const setClauses = columnsUpdated + .map(colName => `${colName} = '${formData[colName]}'`) + .join(', '); + const whereClause = Object.keys(pks) + .map(pk => `${pk} = ${pks[pk]}`) + .join(' AND '); + + return ` + START TRANSACTION; + UPDATE ${schema}.${table} SET ${setClauses} WHERE (${whereClause}); + SELECT ${columnsUpdated.join(', ')} FROM ${schema}.${table} WHERE (${whereClause}); + COMMIT; + `; +}; + +export const generateInsertSqlQuery = ( + schema, + table, + formData, + columnsUpdated, + createModelDefault +) => { + const columns = [createModelDefault.field, ...columnsUpdated].join(', '); + const values = [ + createModelDefault.value, + ...columnsUpdated.map(colName => `'${formData[colName]}'`) + ].join(', '); + + return ` + START TRANSACTION; + INSERT INTO ${schema}.${table} (${columns}) VALUES (${values}); + SELECT id, ${columnsUpdated.join(', ')} FROM ${schema}.${table} WHERE (id = LAST_INSERT_ID()); + COMMIT; + `; +}; diff --git a/src/pages/Account/AddressDetails.vue b/src/pages/Account/AddressDetails.vue index 067a47a5..c41b47e9 100644 --- a/src/pages/Account/AddressDetails.vue +++ b/src/pages/Account/AddressDetails.vue @@ -16,7 +16,7 @@ const vnFormRef = ref(null); const countriesOptions = ref([]); const provincesOptions = ref([]); const pks = { id: route.params.id }; -const formMode = route.params.id === '0' ? 'create' : 'update'; +const isEditMode = route.params.id !== '0'; const fetchAddressDataSql = { query: ` SELECT a.id, a.street, a.nickname, a.city, a.postalCode, a.provinceFk, p.countryFk @@ -74,7 +74,7 @@ onMounted(() => getCountries()); value: 'account.myUser_getId()' }" :pks="pks" - :mode="formMode" + :isEditMode="isEditMode" :title="t('addEditAddress')" table="myAddress" schema="hedera"