I have the following table:
// names of the attributes are changed.
// But I need a column to store a list of JSON.
return knex.schema
.createTable("table_name", table => {
table.string("id", 40).notNullable();
table.string("name", 40).notNullable();
table.primary(["id", "name"]);
table.specificType("some_list", "jsonb[]");
})
};
I have written a query that does the following:
- If the primary key is not there in the table then create a row, but if it is already there then append the respective list entry at the end of the some_list array.
- The condition to append is that the some_list array length should be equal to a received index, called lastReceivedIndex in the code below.
The query is the following:
try {
await OperationMaster.transaction(async (trx) => {
const updatedRows = await trx.raw(
`UPDATE operation_details
SET some_list= array_append(list_item, ?)
WHERE meeting_id = ? AND part_spec = ? AND array_length(some_list, 1) = ? RETURNING CARDINALITY(some_list)`,
[list_item, id, ops.name, lastReceivedIndex]
);
if(updatedRows.rowCount === 0){
const existingEntry = await OperationMaster.query(trx)
.where('id', id)
.andWhere('name', ops.name)
.first()
.forUpdate();
if(!existingEntry){
await OperationMaster.query(trx)
.insert({
'id' : id,
'name' : ops.m_partSpec,
'some_list' : [list_item],
})
.forUpdate();
indexWhereOperationIsAdded = 1; // I want the index where the item was appended.
operationSuccess = true;
}
}
else{
indexWhereOperationIsAdded = updatedRows.rows[0]?.cardinality; // It is known that there will be only one row that will be updated here
operationSuccess = true;
}
});
}
catch (error) {
console.log('Error inserting or appending:', error, newOperationJSON);
}
return [indexWhereOperationIsAdded, operationSuccess];
I am using many array functions that are PostgreSQL specific, but I want a Knex-based query for it. Please suggest any better way to design a schema for this use case.