{"id":14384709,"url":"https://github.com/marmelab/coPostgresQuery","last_synced_at":"2025-08-23T17:33:23.522Z","repository":{"id":57201836,"uuid":"43151276","full_name":"marmelab/coPostgresQuery","owner":"marmelab","description":"Query builder for PostgreSQL in Node.js, built for async","archived":true,"fork":false,"pushed_at":"2019-04-17T14:01:52.000Z","size":487,"stargazers_count":11,"open_issues_count":1,"forks_count":2,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-12-18T19:11:31.405Z","etag":null,"topics":["node","postgresql"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marmelab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-25T14:49:39.000Z","updated_at":"2023-06-10T06:34:54.000Z","dependencies_parsed_at":"2022-09-12T23:50:15.376Z","dependency_job_id":null,"html_url":"https://github.com/marmelab/coPostgresQuery","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmelab%2FcoPostgresQuery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmelab%2FcoPostgresQuery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmelab%2FcoPostgresQuery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marmelab%2FcoPostgresQuery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marmelab","download_url":"https://codeload.github.com/marmelab/coPostgresQuery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230716618,"owners_count":18269807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["node","postgresql"],"created_at":"2024-08-28T18:01:36.246Z","updated_at":"2024-12-21T12:30:51.849Z","avatar_url":"https://github.com/marmelab.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003ctable\u003e\n        \u003ctr\u003e\n            \u003ctd\u003e\u003cimg width=\"20\" src=\"https://cdnjs.cloudflare.com/ajax/libs/octicons/8.5.0/svg/archive.svg\" alt=\"archived\" /\u003e\u003c/td\u003e\n            \u003ctd\u003e\u003cstrong\u003eArchived Repository\u003c/strong\u003e\u003cbr /\u003e\n            This code is no longer maintained. Feel free to fork it, but use it at your own risks.\n        \u003c/td\u003e\n        \u003c/tr\u003e\n\u003c/table\u003e\n\n# coPostgresQueries\n\nUtility to generate and execute postgresql queries with ease.\n\n**Requirements**\n- Node.js \u003e= 6\n- PostgreSQL \u003e= 9.5\n\n## Install\n\n`npm install --save co-postgres-queries`\n\n## Introduction\n\nThe library can be divided in two parts:\n\n1.  [`PgPool`](#pgpool), that allows to connect to the postgres database and execute queries.\n\n```js\nimport PgPool from \"co-postgres-queries\";\nconst clientOptions = {\n  user,\n  password,\n  database,\n  host,\n  port\n};\nconst pool = new PgPool(clientOptions);\n\npool\n  .connect()\n  .then(client =\u003e {\n    return client.query(\"SELECT * from user WHERE firstname = $firstname\", {\n      firstname: \"john\"\n    });\n  })\n  .then(rows =\u003e {\n    // do something with all the user named john\n  });\n```\n\n2.  The [querybuilders](#query-builder) (insertOne, selectOne, etc..) that allows to generate sql, and the corresponding parameters.\n\nEach query builder takes the form:\n\n```js\nquery(config)(...parameters);\n```\n\nOn the first call it receives its configuration, eg, the table name, column name, etc...\nFor example:\n\n```js\nimport insertOne from \"co-postgres-queries/queries/insertOne\";\nconst insertOne = insertOne({\n  table: \"user\",\n  writableCols: [\"name\", \"firstname\"],\n  returnCols: [\"id\", \"name\", \"firstname\"]\n});\n```\n\nOn the second call it takes the query parameters and returns an object of the form `{ sql, parameters }`,\n\n- sql: the sql string that may contain named parameters\n- parameters: the sanitized named parameters and their values.\n\nFor example:\n\n```js\ninsertOne({ name: 'doe', firstname: 'john', other: 'data' });\n// would return\n{\n    sql: 'INSERT INTO user (name, firstname)VALUES($name, $firstname) RETURNING id, name, firstname',\n    parameters: { name: 'doe', firstname: 'john' }\n}\n```\n\nThe result can then be directly passed to [`client.query`](#clientquery) to be executed.\n\n```js\nclient.query(insertOne({ name: \"doe\", firstname: \"john\", other: \"data\" }));\n```\n\nThere is also a [`crud`](#crud) helper function to generate basic crud queries for a given table:\n\n```js\nconst userCrud = crud({\n  table: \"user\",\n  primaryKey: \"id\",\n  writableCols: [\"name\", \"firstname\", \"mail\"],\n  returnCols: [\"id\", \"name\", \"firstname\", \"mail\"]\n});\n```\n\nThis will configure query builders for `selectOne`, `select`, `insert`, `updateOne`, `deleteOne`, `countAll` and `batchInsert` in one literal.\n\ncoPostGresQueries provides the [`saga`](#clientsaga) command to execute the generated query as effect in a generator.\n\n```js\nfunction* subscribeUser(userId) {\n    try {\n        yield begin(); // begin transaction block\n        const user = yield userCrud.selectOne(userId);\n\n        if (!user) {\n            throw new Error('not found');\n        }\n\n        yield userCrud.updateOne(userId, { subscribed: true });\n\n        // ... some other queries\n\n        yield commit();\n        return result;\n    } catch (error) {\n        yield rollback();\n        throw error;\n    }\n    ...\n}\n\nclient.saga(getUserAndDoSomething(5)).then(...);\n```\n\nsince the generator yield only query objects, it is easily testable.\n\n## Api\n\n### PgPool\n\nExtends [node-pg-pool](https://github.com/brianc/node-pg-pool)\nAllows to connect to postgresql and execute query\nIt adds:\n\n- Support for named parameters.\n- query: Now return the list of results.\n- Added queryOne: Same as query but return only one result instead of an array.\n- Helper method ([begin](#begin), [savepoint](#savepoint), [rollback](#rollback), [commit](#commit) to handle transactions on the client.\n- Helper method ([link][#clientlink]) to link a query helper to the client or pool.\n\n#### Creating a pool\n\n```js\nimport PgPool from \"co-postgres-queries\";\nconst clientOptions = {\n  user,\n  password,\n  database,\n  host,\n  port\n};\nconst poolingOptions = {\n  max, // Max number of clients to create (defaults to 10)\n  idleTimeoutMillis // how long a client is allowed to remain idle before being closed (defaults to 30 000 ms)\n};\nconst pool = new PgPool(clientOptions, poolingOptions);\n```\n\n#### Getting client with promise\n\n```js\nconst pool = new pgPool();\npool.connect().then(client =\u003e {\n  // use the client\n});\n\n// async/await\n(async () =\u003e {\n  const pool = new pgPool();\n  const client = await pool.connect();\n})();\n\n// co\nco(function*() {\n  const pool = new pgPool();\n  const client = yield pool.connect();\n});\n```\n\n#### client.query\n\nExecutes a query, it takes three parameters:\n\n- sql: the sql to execute\n- parameters: the parameters to inject in the sql (it use named parameters)\n- returnOne: Optional, if set to true, returns only the first result instead of an array.\n\n```js\n// query use named parameter\nclient\n  .query(\"SELECT $name::text as name\", { name: \"world\" }) // query return a promise\n  .then(result =\u003e {\n    // result contain directly the row\n    console.log(`Hello ${result[0].name}`);\n  });\n\n// It work with async/await\n(async () =\u003e {\n  const pool = new PgPool();\n  const result = await pool.query(\"SELECT $name::text as name\", {\n    name: \"world\"\n  });\n\n  console.log(`Hello ${result[0].name}`);\n})();\n// Or with co\nco(function*() {\n  const pool = new PgPool();\n  const result = yield pool.query(\"SELECT $name::text as name\", {\n    name: \"world\"\n  });\n\n  console.log(`Hello ${result[0].name}`);\n});\n```\n\n`client.query` can also be called with an object literal:\n\n```js\npool.query({\n  sql: \"SELECT $name::text as name\",\n  parameters: { name: \"world\" }\n});\n```\n\n#### pool.query\n\nYou can also execute a query directly from the pool.\nA client will then get automatically retrieved, and released once the query is done.\nTransactions are not possible this way since the client would change on each query.\n\n#### client.link\n\nTakes a query or a literal of query and returns a function that Takess the query parameter and executes it\n\n```js\nconst query = insertOneQuery('table', ['col1', 'col2']);\n\nconst insertOne = client.link(query);\n\nyield insertOne({ col1: 'val1', col2: 'val2' });\n\n// or\nconst queries = crudQueries(table, ['col1', 'col2'], ['col1']);\n\nconst crud = client.link(queries);\n\nyield crud.insertOne({ col1: 'val1', col2: 'val2' });\n```\n\n#### client.release\n\nReturns the client to the pool, to be used again.\nDo not forget to call this when you are done.\n\n#### client.end\n\nCloses the client. It will not return to the pool.\n\n#### client.saga\n\nTakes a generator yielding object queries (`{ sql, parameters }`), and returns an async function that run the generator executing the yielded query.\n\n```js\nfunction* getUserAndDoSomething(id) {\n    const user = yield {\n        sql: 'SELECT * FROM user WHERE $id=id',\n        parameters: { id },\n        returnOne: true,\n    };\n    ...\n}\n\nclient.saga(getUserAndDoSomething(5)).then(...);\n```\n\nThe yielded query object will be internally passed to `client.query` then the result will be passed back to the generator.\nIf an error occurs during the query, it will be thrown back into the generator where it can be catched.\n\n```js\nconst executeQUery = client.saga(function* (id) {\n    try {\n        const user = yield {\n            sql: 'bad query',\n        };\n        ...\n    } catch (error) {\n        // handle the error\n    }\n});\n```\n\nSince the queries functions return query object, they can be yielded.\n\n```js\nconst selectOneUserById = selectOne({ table: 'user' });\n\nconst getUserAndDoSomethig = client.saga(function* (id) {\n    const user = yield selectOneByUserId({ id });\n    ...\n});\n```\n\nYou can also yield an array of query to be run in parallel:\n\n```js\nconst getUserAndCommands = client.saga(function* (id) {\n    const [user, commands] = yield [\n        selectOneByUserId({ id }),\n        selectCommandsByUserId({ id }),\n    ];\n    ...\n});\n```\n\nOr even a literal:\n\n```js\nconst getUserAndCommands = client.saga(function* (id) {\n    const { user, commands } = yield {\n        user: selectOneByUserId({ id }),\n        commands: selectCommandsByUserId({ id }),\n    };\n    ...\n});\n```\n\nSince the generator yield plain objects, they can be easily tested without needing any mocks:\n\n```js\nconst iterator = someQueryGenerator();\nconst {\n  value: { sql, parameters }\n} = iterator.next();\n// we get the generated sql and parameters.\n\niterator.next(queryResult); // we can pass what we want as result\n\niterator.throw(queryError); // or we can resume by throwing error\n```\n\n### Query builder\n\nEach query helper takes the form:\n\n```js\nquery(config)(...parameters);\n```\n\nOn the first call it receives its configuration, eg, the table name, column name, etc...\nFor example:\n\n```js\nimport insertOne from \"co-postgres-queries/queries/insertOne\";\nconst insertOne = insertOne({\n  table: \"user\",\n  writableCols: [\"name\", \"firstname\"],\n  returnCols: [\"id\", \"name\", \"firstname\"]\n});\n```\n\nOn the second call it takes the query parameters and returns an object of the form `{ sql, parameters }`,\nwith the sql containing named parameter, and parameters having been sanitized based on the configuration.\nFor example:\n\n```js\ninsertOne({ name: 'doe', firstname: 'john', other: 'data' });\n// would return\n{\n    sql: 'INSERT INTO user (name, firstname)VALUES($name, $firstname) RETURNING id, name, firstname',\n    parameters: { name: 'doe', firstname: 'john' }\n}\n```\n\nThe result can then be directly passed to `client.query` to be executed.\n\n#### insertOne\n\n```js\nimport insertOne from \"co-postgres-queries/queries/insertOne\";\ninsertOne({ table, writableCols, returnCols })(row);\n```\n\nReturns a query to insert one given row.\n\n##### Configuration\n\n- table: the table name\n- writableCols: lisft of columns that can be set\n- returnCols: list of columns exposed in the result of the query\n\n##### Parameters\n\nA literal object in the form of:\n\n```js\n{\n    column: value,\n    ...\n}\n```\n\n#### batchInsert(table, writableCols, returnCols)(rows)\n\n```js\nimport batchInsert from \"co-postgres-queries/queries/batchInsert\";\nbatchInsert(table, writableCols, returnCols)(rows);\n```\n\nallow to create a query to insert an array of rows.\n\n##### Configuration\n\n- table: the table name\n- writableCols: list of columns that can be set\n- returnCols: list of columns exposed in the result of the query\n\n##### Parameters\n\nAn array of literal objects in the form of:\n\n```js\n[\n    {\n        column: value,\n        ...\n    }, ...\n]\n```\n\n#### selectOne\n\n```js\nimport selectOne from \"co-postgres-queries/queries/selectOne\";\nselectOne({ table, primaryKey, returnCols, permanentFilters })(row);\n```\n\nCreates a query to select one row.\n\n##### Configuration\n\n- table: the table name\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- returnCols: list of columns retrieved by the query\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nA literal in the form of:\n\n```js\n{\n    id1: value,\n    id2: value,\n    ...\n}\n```\n\nAny key not present in primaryKey will be ignored.\n\n#### select\n\n```js\nimport select from \"co-postgres-queries/queries/select\";\nselect({\n  table,\n  primaryKey,\n  returnCols,\n  searchableCols,\n  specificSorts,\n  groupByCols,\n  withQuery,\n  permanentFilters,\n  returnOne\n})({ limit, offset, filters, sort, sortDir });\n```\n\nCreates a query to select one row.\n\n##### Configuration\n\n- table:\n  the table name, accept JOIN statements    \n  exemple:\n\n  ```js\n  {\n    table: 'table1 JOIN table2 ON table1.table2_id = table2.id'\n  }\n  ```\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- returnCols:\n  list of columns retrieved by the query\n- searchableCols:\n  list of columns that can be searched (usable in filter parameter). Defaults to return columns\n- specificSorts:\n  allow to specify sort order for a given column. Useful when we want to order string other than by alphabetical order.\n  example:\n  ```js\n  {\n    level: [\"master\", \"expert\", \"novice\"];\n  }\n  ```\n  will order level column with all master first, then expert and finally novice\n- groupByCols\n  allow to add a GROUP BY clause to the query on the given columns\n- withQuery\n  specify that we want to encompass the query in `WITH RESULT AS \u003cquery\u003e SELECT * FROM result`\n  This add a temporary result table that allow to sort on computed and joined column.\n  if the table configuration contain a JOIN clause, this will be automatically set to true.\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n- returnOne: Optional, if set to true, returns only the first result instead of an array.\n\n##### Parameters\n\nA literal object with:\n\n* **limit:** number of results to be returned\n* **offset:** number of results to be ignored\n* **filters:** a object taking as keys the column to filter on and as values the filter values\n\nFor instance, specifying the following **filters** value:\n\n```js\n{\n    first_name: \"John\",\n    last_name: \"Doe\",\n    last_paid_at: null,\n}\n```\n\nWill produce the following `WHERE` clause:\n\n```sql\nWHERE\n    first_name = 'John'\n    AND last_name = 'Doe'\n    AND last_paid_at IS NULL\n```\n\nOther SQL matching operators may be used by specifying some prefixes to the column names. For instance:\n\n```js\n{\n    not_first_name: \"John\",           // first_name != \"John\"\n    not_last_paid_at: null,           // last_paid_at IS NOT NULL\n    from_last_paid_at: '2010-01-01',  // last_paid_at \u003e= '2010-01-01'\n    to_last_paid_at: '3010-01-01',    // last_paid_at \u003c= '3010-01-01'\n    like_position: 'Sales',           // position ILIKE '%Sales%'\n    not_like_position: 'Manager'      // position NOT ILIKE '%Manager%'\n}\n```\n\nIt is also possible to match to all searchable column with match:\n\n```js\n{\n    match: 'value',\n}\n```\n\n  will return only row for which any searchableCols matching value (case insensitive).\n\n- sort:\n  Specify the column by which to filter the result (Additionally the result will always get sorted by the row identifiers to avoid random order)\n- sortDir:\n  Specify the sort direction, either 'ASC' or 'DESC'\n\n#### countAll\n\n```js\nimport countAll from \"co-postgres-queries/queries/countAll\";\ncountAll({ table, permanentFilters })({ filters: { enabled: true } });\n```\n\nCreate a query to count all rows. It also takes an optional plain object parameter `filters`, applied to the query in addition to the `permanentFilters`.\n\n##### Configuration\n\n- table: the table name\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n#### update\n\n```js\nimport update from \"co-postgres-queries/queries/update\";\nupdate({\n  table,\n  writableCols,\n  filterCols,\n  returnCols,\n  permanentFilters\n})(filters, data);\n```\n\nCreates a query to update rows.\n\n##### Configuration\n\n- table: the table name\n- writableCols: the columns that can be updated\n- filterCols: the columns that can be used to filter the updated rows\n- returnCols: the columns to be returned in the result\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nTwo arguments:\n\n- filters:\n  literal specifying wanted value for given column\n  example:\n  ```js\n  {\n    column: \"value\";\n  }\n  ```\n  will update only row for which column equal 'value'\n- data: a literal specifying the new values\n\n#### updateOne\n\n```js\nimport updateOne from \"co-postgres-queries/queries/updateOne\";\nupdateOne({\n  table,\n  writableCols,\n  primaryKey,\n  returnCols,\n  permanentFilters\n})(identifier, data);\n```\n\nCreates a query to update one row.\n\n##### Configuration\n\n- table: the table name\n- writableCols: the columns that can be updated\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- returnCols: the columns to be returned in the result\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nTwo arguments:\n\n- identifier: either a single value for a single primaryKey column, or a literal if several columns:`{ id1: value, id2: otherValue }`. All configured primaryKey columns must be given a value.\n- data: a literal specifying the column to update\n\n#### remove\n\n```js\nimport remove from \"co-postgres-queries/queries/remove\";\nremove({ table, filterCols, returnCols, permanentFilters })(filters);\n```\n\nCreates a query to delete rows.\n\n##### Configuration\n\n- table: the table name\n- filterCols: the columns that can be used to filter the updated rows\n- returnCols: list of columns retrieved by the query\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nA literal specifying wanted value for given column\nexample:\n\n```js\n{\n  column: \"value\";\n}\n```\n\nwill update only row for which column equal 'value'\n\n#### removeOne\n\n```js\nimport removeOne from \"co-postgres-queries/queries/removeOne\";\nremoveOne({ table, primaryKey, returnCols, permanentFilters })(identitfier);\n```\n\nCreates a query to delete one row.\n\n##### Configuration\n\n- table: the table name\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- returnCols: list of columns retrieved by the query\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nThe identifier: either a single value for a single primaryKey column, or a literal if several columns:`{ id1: value, id2: otherValue }`. All configured primaryKey columns must be given a value.\n\n#### batchRemove\n\n```js\nimport batchRemove from \"co-postgres-queries/queries/batchRemove\";\nbatchRemove({ table, primaryKey, returnCols, permanentFilters })(\n  identifierList\n);\n```\n\nAllow to create a query to delete several row at once\n\n##### Configuration\n\n- table: the table name\n- columns: list of columns to insert\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nThe list of identifier either an array of single value for a single primaryKey column, or an array of literal if several columns:`[{ id1: value, id2: otherValue }, ...]`. All configured primaryKey columns must be given a value.\n\n#### upsertOne\n\n```js\nimport upsertOne from \"co-postgres-queries/queries/upsertOne\";\nupsertOne({\n  table,\n  primaryKey,\n  writableCols,\n  returnCols,\n  permanentFilters\n})(row);\n```\n\nCreates a query to update one row or create it if it does not already exists.\n\n##### Configuration\n\n- table: the name of the table\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- writableCols: the column that can be updated\n- returnCols: the column to return in the result\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nthe row to upsert\n\n#### batchUpsert\n\n```js\nimport batchUpsert from \"co-postgres-queries/queries/batchUpsert\";\nbatchUpsert({\n  table,\n  primaryKey,\n  writableCols,\n  returnCols,\n  permanentFilters\n})(rows);\n```\n\nCreates a query to update a batch row creating those that does not already exists.\n\n##### Configuration\n\n- table: the name of the table in which to upsert\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- writableCols: the column that can be updated\n- returnCols: the column to return in the result\n- columns: all the columns accepted by the query, default to selectorcolumns + writableCols (no reason to change that)\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n##### Parameters\n\nThe array of rows to upsert\n\n#### selectByOrderedIdentifiers\n\n```js\nimport selectByOrderedIdentifiers from \"co-postgres-queries/queries/selectByOrderedIdentifiers\";\nselectByOrderedIdentifiers({\n  table,\n  primaryKey,\n  returnCols\n})(values);\n```\n\nCreates a query to select multiple row given an array of identifier. The result will keep the order of the identifier. Due to the nature of the query, this will only work for primaryKey composed of a single column.\n\n##### Configuration\n\n- table: the name of the table in which to upsert\n- primaryKey: primaryKey of the table (this will only work with primaryKey of a single column)\n- returnCols: the column to return in the result\n\n##### Parameters\n\nThe array of identifier to retrieve. The array order will determine the result order.\n\n#### crud\n\n```js\nimport crud from \"co-postgres-queries/queries/crud\";\ncrud({\n  table,\n  writableCols,\n  primaryKey,\n  returnCols,\n  permanentFilters\n});\n```\n\nCreates configured queries for insertOne, batchInsert, selectOne, select, updateOne, deleteOne and batchDelete.\n\n##### Configuration\n\n- table: the name of the table.\n- primaryKey: One or more columns representing the primary key. Accept either an array or a single value. (default: `id`)\n- writableCols: list of columns that can be set\n- returnCols: the list of columns we want returned as result.\n- searchableCols: the columns that can be searched (usable in filter parameter). Defaults to return columns\n- specificSorts:\n  allow to specify sort order for a given column. Useful when we want to order string other than by alphabetical order.\n  example:\n  ```js\n  {\n    level: [\"master\", \"expert\", \"novice\"];\n  }\n  ```\n  will order level column with all master first, then expert and finally novice\n- groupByCols: allow to add a GROUP BY clause to the query on the given columns\n- withQuery:\n  specify that we want to encompass the query in `WITH RESULT AS \u003cquery\u003e SELECT * FROM result`\n  This add a temporary result table that allow to sort on computed and joined column.\n  if the table configuration contain a JOIN clause, this will be automatically set to true.\n- permanentFilters: List of filters applied by default, e. g. for a soft delete with permanentFilters as `{ deleted_at: null}`\n\n#### transaction helper\n\n```js\nimport {\n  begin,\n  commit,\n  savepoint,\n  rollback\n} from \"co-postgres-queries/queries/transaction\";\n```\n\nSimple helper to manage transaction\nYou must retrieve a client with `pool.connect()` to use those.\n\n##### begin\n\n```js\nimport begin from \"co-postgres-queries/queries/transaction/begin\";\nbegin();\n// { sql: 'BEGIN' }\n```\n\ncreate a query to start a transaction\n\n##### commit\n\n```js\nimport commit from \"co-postgres-queries/queries/transaction/commit\";\ncommit();\n// { sql: 'COMMIT' }\n```\n\ncreate a query to commit a transaction\n\n##### savepoint\n\n```js\nimport savepoint from \"co-postgres-queries/queries/transaction/savepoint\";\nsavepoint(name);\n// { sql: 'SAVEPOINT name' }\n```\n\ncreate a query to add a save point during transsaction\n\n##### rollback\n\n```js\nimport rollback from \"co-postgres-queries/queries/transaction/rollback\";\nrollback();\n// { sql: 'ROLLBACK' }\n// or\nrollback(name);\n// { sql: 'ROLLBACK to name' }\n```\n\nRollback the transaction to the given save point, or to its beginning if not specified.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarmelab%2FcoPostgresQuery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarmelab%2FcoPostgresQuery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarmelab%2FcoPostgresQuery/lists"}