new way in progress

This commit is contained in:
arttu
2024-07-03 12:05:00 +03:00
committed by ShootingStar91
parent 1f654e5560
commit ce849270c6
4 changed files with 117 additions and 142 deletions
+6 -22
View File
@@ -2,16 +2,14 @@ import { logDb, nowDb, pool } from '../utils/db'
import { EditDataType, LocalityDetailsType } from '../../../frontend/src/backendTypes'
import Prisma from '../../prisma/generated/now_test_client'
import { validateLocality } from '../../../frontend/src/validators/locality'
import { diff } from 'deep-object-diff'
import { filterFields } from './writeUtils'
import { ValidationObject } from '../../../frontend/src/validators/validator'
import { logger } from '../utils/logger'
import { fixBigInt } from '../utils/common'
import { testWrite } from './write'
import { write } from './write/write'
export const getAllLocalities = async (onlyPublic: boolean) => {
const where = onlyPublic ? { loc_status: false } : {}
await testWrite()
console.log('moi')
const result = await nowDb.now_loc.findMany({
select: {
lid: true,
@@ -30,7 +28,6 @@ export const getAllLocalities = async (onlyPublic: boolean) => {
export const getLocalityDetails = async (id: number) => {
// TODO: Check if user has access
const result = await nowDb.now_loc.findUnique({
where: { lid: id },
include: {
@@ -80,14 +77,7 @@ export const getLocalityDetails = async (id: number) => {
updates: logResult.filter(logRow => logRow.luid === lau.luid),
}))
if (!result) return null
const { now_ls, now_mus, now_plr, ...locality } = result
const localityDetails = {
...locality,
museums: now_mus.map(museum => museum.com_mlist),
projects: now_plr.map(project => project.now_proj),
species: now_ls.map(species => species.com_species),
}
return JSON.parse(fixBigInt(localityDetails)!) as LocalityDetailsType
return JSON.parse(fixBigInt(result)!) as LocalityDetailsType
}
export const fixEditedLocality = (editedLocality: EditDataType<LocalityDetailsType>) => {
@@ -110,15 +100,9 @@ export const validateEntireLocality = (editedFields: EditDataType<Prisma.now_loc
export const processLocalityForEdit = async (editedLocality: EditDataType<LocalityDetailsType>) => {
const fixedEditedLocality = fixEditedLocality(editedLocality)
const oldLocality = await getLocalityDetails(fixedEditedLocality.lid!)
const difference = diff(oldLocality!, fixedEditedLocality)
const { filteredFields, filteredObject } = filterFields(
difference as EditDataType<LocalityDetailsType>,
nowDb.now_loc.fields as unknown as Record<string, unknown>
)
const validationErrors = validateEntireLocality(filteredObject)
if (validationErrors.length > 0) return { validationErrors }
const result = await writeLocality(oldLocality!.lid, filteredFields)
// const validationErrors = validateEntireLocality(editedLocality)
// if (validationErrors.length > 0) return { validationErrors }
const result = write(editedLocality, 'now_loc', oldLocality!)
return { result }
}
-119
View File
@@ -1,119 +0,0 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import {
EditDataType,
LocalityDetailsType,
SpeciesDetailsType,
TimeBoundDetailsType,
TimeUnitDetailsType,
} from '../../../frontend/src/backendTypes'
import { diff } from 'deep-object-diff'
import { isNumeric, printJSON, revertFieldNames } from './writeUtils'
type WriteFunction = (
data: EditDataType<LocalityDetailsType | SpeciesDetailsType | TimeUnitDetailsType | TimeBoundDetailsType>,
tableName: string,
oldObject: EditDataType<LocalityDetailsType | SpeciesDetailsType | TimeUnitDetailsType | TimeBoundDetailsType>
) => string
const ids = { now_loc: 'lid', now_ls: ['lid', 'species_id'] }
type Item = { column: string; value: any }
type WriteItem = { table: string; type: 'add' | 'update' | 'delete'; items: Item[] }
export const write: WriteFunction = (data, tableName, oldObject) => {
console.log('Write')
const writeList: WriteItem[] = []
const writeTable = (data: object, tableName: string, oldObject: object, parentTable?: string) => {
console.log(
`writeTable called tableName: ${tableName}\n, oldObject: ${oldObject === undefined ? 'undefined' : 'is defined'}\n, parentTable: ${parentTable}`
)
const rowsToDelete: { table: string; rowId: string }[] = []
const fieldsToWrite: any[] = []
for (const field of Object.keys(data)) {
const value = data[field as keyof object] as string | number | undefined
console.log(`Field ${field}`)
if (Array.isArray(value)) {
console.log('Writing array:')
for (const [index, item] of value.entries()) {
console.log(`* Index: ${index} Item: ${printJSON(item)}`)
const oldArray = oldObject[field]
const oldItem = oldArray?.[index]
writeTable(item, field, oldItem, tableName)
}
return
}
if (isNumeric(field)) {
console.log('is numeric')
// We are iterating what was an array in original data
if (value === undefined) {
// Mark row to be deleted from join table
const oldId = oldObject[field as keyof object]
rowsToDelete.push({ table: tableName, rowId: oldId })
continue
}
if (typeof value === 'object') {
writeTable(value, tableName, oldObject)
continue
}
} else if (typeof value === 'string' || typeof value === 'number') {
fieldsToWrite.push({ field, value: data[field] })
}
if (typeof value === 'object') {
writeTable(value, field, oldObject[field], tableName)
}
}
if (fieldsToWrite.length === 0) return
const oldId = oldObject?.[ids[tableName]]
const result =
oldId === undefined
? writeList.push({ type: 'add', items: fieldsToWrite, table: tableName }) //query(`INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (?) RETURNING ${ids[tableName]}`, values)
: writeList.push({ type: 'update', items: fieldsToWrite, table: tableName }) //query(`UPDATE ${tableName} SET ${columns.map(c => `${c} = ?`).join(', ')} RETURNING ${ids[tableName]}`, [ ...values,])
return { id: result[ids[tableName]] }
}
console.log('Old object', JSON.stringify(oldObject, null, 2))
console.log('New object', JSON.stringify(data, null, 2))
const diffData = diff(oldObject, data)
console.log('diff', printJSON(diffData))
writeTable(diffData, tableName, oldObject)
console.log(JSON.stringify(writeList, null, 2))
return 'ok'
}
const query = (queryString: string, values: unknown[]) => {
console.log(`${queryString} | values: ${values}`)
return 'ok'
}
export const testUpdate = () => {
const oldLoc = {
lid: 1,
age_comm: 'old comment',
now_ls: [
{
lid: 2,
species_id: 2,
nis: 100,
},
],
}
const editedFields = {
age_comm: 'write-testi',
max_age: 5000,
now_ls: [{ lid: 2, species_id: 2, source_name: 'locci' }],
}
write(revertFieldNames({ ...oldLoc, ...editedFields }), 'now_loc', oldLoc)
}
export const testWrite = () => {
console.log('testing update')
testUpdate()
}
+110
View File
@@ -0,0 +1,110 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import {
EditDataType,
LocalityDetailsType,
SpeciesDetailsType,
TimeBoundDetailsType,
TimeUnitDetailsType,
} from '../../../../frontend/src/backendTypes'
import { revertFieldNames } from './writeUtils'
type WriteFunction = (
data: EditDataType<LocalityDetailsType | SpeciesDetailsType | TimeUnitDetailsType | TimeBoundDetailsType>,
tableName: string,
oldObject: EditDataType<LocalityDetailsType | SpeciesDetailsType | TimeUnitDetailsType | TimeBoundDetailsType>
) => string
const ids = { now_loc: 'lid', now_ls: 'species_id' }
type Item = { column: string; value: any }
type WriteItem = { table: string; type: 'add' | 'update' | 'delete'; items: Item[] }
const getFindFunction = (tableName: string, newItem: any) => (item: any) => {
if (tableName === 'now_ls') {
// todo this should be com species when it is fixed
if (item.species_id === newItem.species_id) return true
}
return false // TODO add all types
}
// TODO change ignored fields to allowed fields. form those by taking prisma.model.fields, and adding the accepted relation fields.
const ignoredFields = ['now_lau']
export const write: WriteFunction = (data, tableName, oldObject) => {
console.log('Write')
const writeList: WriteItem[] = []
const writeTable = (obj: object, tableName: string, oldObj: object | null) => {
console.log(
`writeTable called tableName: ${tableName}\n'} ${oldObj ? ' oldobj defined ' : ' no old object found '}`
)
const allFields = Object.keys(obj).filter(f => !ignoredFields.includes(f))
const fields = allFields.filter(f => typeof obj[f as keyof object] !== 'object' || obj[f as keyof object] === null)
const relationFields = allFields.filter(
f => typeof obj[f as keyof object] === 'object' && obj[f as keyof object] !== null
)
console.log('fields: ', JSON.stringify(fields))
console.log('relations: ', JSON.stringify(relationFields))
const fieldsToWrite: Item[] = []
const rowsToDelete: Item[] = []
for (const field of fields) {
const newValue = obj[field as keyof object] as any
const oldValue = oldObj?.[field as keyof object]
if (newValue === oldValue) continue
console.log(
`Field: ${field} Old value: ${oldValue} - ${typeof oldValue} New value: ${newValue} - ${typeof newValue}`
)
fieldsToWrite.push({ column: field, value: newValue })
}
const columns = fieldsToWrite.map(({ column }) => column)
const values = fieldsToWrite.map(({ value }) => value)
const idFieldName = ids[tableName as keyof object] as string
let id = obj[idFieldName as keyof object] as string
if (values.length > 0) {
if (id) {
query(`UPDATE ${tableName} SET ${columns.map(c => `${c} = ?`).join(', ')} RETURNING ${idFieldName}`, [
...values,
])
} else {
id = query(`INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (?) RETURNING ${idFieldName}`, values)
}
}
for (const relationField of relationFields) {
const value = obj[relationField]
if (Array.isArray(value)) {
const toBeDeleted: Item[] = value
.filter(({ rowState }) => rowState === 'removed')
.map(item => ({ column: relationField, value: item[idFieldName] }))
rowsToDelete.push(...toBeDeleted)
for (const item of value.filter(({ rowState }) => rowState !== 'removed')) {
const itemWithId = { ...item } // TODO add id here when join tables added
// console.log('item', item, JSON.stringify(item))
writeTable(itemWithId, relationField, oldObj[relationField].find(getFindFunction(relationField, itemWithId)))
}
} else {
// writing a relation object
const itemWithId = { ...value, [idFieldName]: id }
writeTable(itemWithId, relationField, oldObj?.[relationField as keyof object] as any)
}
}
rowsToDelete.map(item => query(`DELETE FROM ? WHERE ? = ?`, [item.column, ids[item.column], item.value])) // NOTE column here is actually table name
//console.log(JSON.stringify(fieldsToWrite, null, 2))
}
console.log('Old object', JSON.stringify(oldObject, null, 2))
console.log('New object', JSON.stringify(data, null, 2))
writeTable(revertFieldNames(data), tableName, revertFieldNames(oldObject))
// console.log(JSON.stringify(writeList, null, 2))
return 'ok'
}
const query = (queryString: string, values: any[]) => {
console.log(`${queryString} | values: ${values.join(', ')}`)
return 'some_id'
}
@@ -1,7 +1,7 @@
/*
common utility functions for processing saving actions
*/
import { EditDataType } from '../../../frontend/src/backendTypes'
import { EditDataType } from '../../../../frontend/src/backendTypes'
/*
Returns object where only the "original" fields remain.