Fix booleans and other loc relation writes, except project for now

This commit is contained in:
ShootingStar91
2024-08-25 18:13:23 +03:00
parent 35f12d3082
commit d58512e540
4 changed files with 28 additions and 14 deletions
+1
View File
@@ -28,6 +28,7 @@ export const writeLocality = async (locality: EditDataType<LocalityDetailsType>)
const { species_id } = await writeHandler.createObject('com_species', species, ['species_id'])
species.species_id = species_id as number
}
await writeHandler.upsertList('now_ls', locality.now_ls, ['lid', 'species_id'])
await writeHandler.upsertList('now_mus', locality.now_mus, ['lid', 'museum'])
await writeHandler.upsertList('now_ss', locality.now_ss, ['lid', 'sed_struct'])
@@ -66,10 +66,13 @@ export class DatabaseHandler {
const columnsString = columns.length === 0 ? '*' : columns.map(col => `${this.dbName}.${col}`).join(', ')
const { columns: idColumns, values: idValues } = this.getValuesAndColumns(ids)
const whereClause = createWhereClause(idColumns)
return await this.executeQuery<T>(
`SELECT ${columnsString} FROM ${this.dbName}.${table} WHERE ${whereClause}`,
idValues
)
const returnValue = (
await this.executeQuery<T[]>(
`SELECT ${columnsString} FROM ${this.dbName}.${table} WHERE ${whereClause}`,
idValues
)
)[0]
return returnValue
}
async executeQuery<T>(query: string, values?: Array<DbValue>) {
@@ -25,3 +25,9 @@ export const getItemList = (object: Record<string, unknown>, skipEmptyValues?: b
if (skipEmptyValues) return list.filter(item => item.value !== '')
return list
}
export const fixBoolean = (value: unknown) => {
if (value === false) return 0
if (value === true) return 1
return value as DbValue
}
@@ -1,7 +1,7 @@
import { RowState } from '../../../../frontend/src/backendTypes'
import { AllowedTables, DbValue, PrimaryTables, WriteItem } from '../write/writeUtils'
import { DatabaseHandler, DbWriteItem } from './databaseHandler'
import { getItemList, valueIsDifferent } from './utils'
import { fixBoolean, getItemList, valueIsDifferent } from './utils'
/* Handles writing logic that are agnostic of datatype, but not directly operations to db. */
/* Usage: after constructor, initialize with writeHandler.start. Assign value to idValue whever you have it. */
@@ -36,50 +36,54 @@ export class WriteHandler extends DatabaseHandler {
async updateRow<T extends Record<string, DbValue>>(table: AllowedTables, items: DbWriteItem[], ids: DbWriteItem[]) {
const oldObject = await super.select<T>(table, [], ids)
const fieldsToWrite: DbWriteItem[] = []
// TODO put oldValue here too for logging
for (const { column, value } of items) {
const oldValue = oldObject[column as keyof T]
if (!valueIsDifferent(value, oldValue)) continue
const fixedValue = fixBoolean(value)
if (!valueIsDifferent(fixedValue, oldValue)) continue
fieldsToWrite.push({ column, value })
fieldsToWrite.push({ column, value: fixedValue })
}
if (items.find(item => !this.allowedColumns.includes(item.column))) {
throw new Error('Unallowed column in SQL')
}
this.writeList.push({ table, type: 'update', items: items.map(item => ({ ...item, table })) })
if (fieldsToWrite.length === 0) return
return await super.update(table, fieldsToWrite, ids)
}
async createObject<T extends Record<string, unknown>>(table: AllowedTables, object: T, idColumns: string[]) {
if (idColumns.includes(this.idColumn) && this.idValue && !object[this.idColumn]) {
;(object as Record<string, unknown>)[this.idColumn] = this.idValue
}
const itemsToWrite = getItemList({ ...object }, true)
return await this.createRow<Record<keyof T, DbValue>>(table, itemsToWrite, idColumns)
}
async updateObject<T extends Record<string, unknown>>(table: AllowedTables, object: T, idColumns: string[]) {
const ids = idColumns.map(column => ({ column, value: object[column] as DbValue }))
const itemsToWrite = getItemList(object)
const itemsToWrite = getItemList(object, true)
return await this.updateRow<Record<keyof T, DbValue>>(table, itemsToWrite, ids)
}
async upsertObject<T extends Record<string, unknown>>(table: AllowedTables, object: T, idColumns: string[]) {
if (idColumns.includes(this.idColumn) && this.idValue && !object[this.idColumn]) {
;(object as Record<string, unknown>)[this.idColumn] = this.idValue
return await this.createObject(table, object, idColumns)
}
if (idColumns.find(idCol => !object[idCol])) return await this.createObject(table, object, idColumns)
return await this.updateObject<T>(table, object, idColumns)
}
async upsertList<T extends { rowState?: RowState }>(table: AllowedTables, objects: T[], ids: string[]) {
async upsertList<T extends { rowState?: RowState }>(table: AllowedTables, objects: T[], idColumns: string[]) {
for (const object of objects) {
const rowState = object.rowState
if (rowState === 'new') {
await this.upsertObject(table, object, ids)
await this.createObject(table, object, idColumns)
} else if (rowState === 'removed') {
await this.delete(
table,
ids.map(id => ({ column: id, value: object[id as keyof T] as DbValue }))
idColumns.map(idColumn => ({ column: idColumn, value: object[idColumn as keyof T] as DbValue }))
)
}
}