-1

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.

Shadow
  • 33,525
  • 10
  • 51
  • 64
Kumar Arnav
  • 301
  • 2
  • 13
  • jsonb itself seems Postgre specific – Vivick Aug 14 '23 at 06:57
  • Use of arrays is often an indicator of incorrect relational database design. Store the array values in separate lookup tables as rows. This design will be supported by all relational databases. – Shadow Aug 14 '23 at 08:24
  • While you can transform this to knex you'll end up using `raw` statements and it will *not* be db-agnostic. – Michel Floyd Aug 14 '23 at 18:02

0 Answers0