ivanceras / curtain

Moved to https://github.com/ivanceras/diwata
https://github.com/ivanceras/diwata
Apache License 2.0
141 stars 4 forks source link

Fix CRUD functionality #1

Open ivanceras opened 8 years ago

ivanceras commented 8 years ago

posting changeset should response

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/37625047-fix-crud-functionality?utm_campaign=plugin&utm_content=tracker%2F28555874&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F28555874&utm_medium=issues&utm_source=github).
jmealo commented 7 years ago

@ivanceras: Kudos on the project so far. Would you mind fleshing out this ticket a bit? I can't tell if you're trying to send multiple records as a transaction or simply want the endpoint to return that information when applicable on a single operation.

If you're grouping multiple operations (and order doesn't matter):

I usually create a giant CTE and then UNION the records. If the records are unlike I use row_to_json. The order in which the queries are executed isn't deterministic/guaranteed IIRC.

Here are simplistic JavaScript examples of what that looks like:

function queriesToReturningCte(queries) {
    var cte = [],
        select = [];

    queries.forEach(function(query, i) {
        query = query.trim();

        // Strip trailing semi-colon
        if (query.slice(-1) === ';') {
            query = query.slice(0, -1);
        }

       if (query.slice(-11).toLowerCase() !== 'returning *') {
           query += ' RETURNING *'
       }

        cte.push(`q${i} AS (${query})`);
        select.push(`SELECT * FROM q${i}`);
    });

    return `WITH ${cte.join(',\n')} ${select.join('\nUNION ALL\n')};`;
}

function queriesToReturningJsonCte(queries) {
    var cte = [],
        select = [];

    queries.forEach(function(query, i) {
        query = query.trim();

        // Strip trailing semi-colon
        if (query.slice(-1) === ';') {
            query = query.slice(0, -1);
        }

        if (query.slice(-11).toLowerCase() !== 'returning *') {
            query += ' RETURNING *'
        }

        cte.push(`q${i} AS (${query})`);
        select.push(`SELECT row_to_json(q${i}) AS json FROM q${i}`);
    });

    return `WITH ${cte.join(',\n')} ${select.join('\nUNION ALL\n')};`;
}

If you introduced an order of operations to apply UPDATE, INSERT and INSERT ON CONFLICT, DELETE you can easily match results to the operations.

This can be somewhat helpful (https://github.com/zhm/pg-query-parser), I'm not sure if you could reverse the error reporting code to reason about any errors coming back.

ivanceras commented 7 years ago

@jmealo Apologize for a long delays on my replies, as I have been busy for this last month.

Yes, the CRUD functionality is sending multiple Operations on multiple data at the same time. I didn't take into consideration at the order of the operations. For now, I just send the operations to the server and just return whatever errors it encountered as the users are performing operations on the records. Errors like foreign key constraint when removing records are displayed as is, and a clue to the user to delete the depending records first if that's what they really want to do, as it can be easily overlooked.

Performing the operations in correct order as the users are doing would be a logical decision to do.