{"id":15390205,"url":"https://github.com/gajus/slonik-utilities","last_synced_at":"2025-07-04T03:38:36.016Z","repository":{"id":34649196,"uuid":"182092348","full_name":"gajus/slonik-utilities","owner":"gajus","description":"Utilities for manipulating data in PostgreSQL database using Slonik.","archived":false,"fork":false,"pushed_at":"2023-06-17T19:42:20.000Z","size":368,"stargazers_count":32,"open_issues_count":12,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T10:21:26.896Z","etag":null,"topics":["postgresql","slonik","upsert"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gajus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-18T13:25:19.000Z","updated_at":"2024-04-23T16:09:48.000Z","dependencies_parsed_at":"2024-06-20T23:38:06.543Z","dependency_job_id":null,"html_url":"https://github.com/gajus/slonik-utilities","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fslonik-utilities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fslonik-utilities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fslonik-utilities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fslonik-utilities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gajus","download_url":"https://codeload.github.com/gajus/slonik-utilities/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248670501,"owners_count":21142901,"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":["postgresql","slonik","upsert"],"created_at":"2024-10-01T15:04:56.484Z","updated_at":"2025-04-14T22:23:20.703Z","avatar_url":"https://github.com/gajus.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca name=\"user-content-slonik-utilities\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities\"\u003e\u003c/a\u003e\n# Slonik Utilities\n\n[![Coveralls](https://img.shields.io/coveralls/gajus/slonik-utilities.svg?style=flat-square)](https://coveralls.io/github/gajus/slonik-utilities)\n[![NPM version](http://img.shields.io/npm/v/slonik-utilities.svg?style=flat-square)](https://www.npmjs.org/package/slonik-utilities)\n[![Canonical Code Style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](https://github.com/gajus/canonical)\n[![Twitter Follow](https://img.shields.io/twitter/follow/kuizinas.svg?style=social\u0026label=Follow)](https://twitter.com/kuizinas)\n\nUtilities for manipulating data in PostgreSQL database using [Slonik](https://github.com/gajus/slonik).\n\n\u003ca name=\"user-content-slonik-utilities-contents\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-contents\"\u003e\u003c/a\u003e\n## Contents\n\n* [Slonik Utilities](#user-content-slonik-utilities)\n    * [Contents](#user-content-slonik-utilities-contents)\n    * [Usage](#user-content-slonik-utilities-usage)\n        * [`update`](#user-content-slonik-utilities-usage-update)\n        * [`updateDistinct`](#user-content-slonik-utilities-usage-updatedistinct)\n        * [`upsert`](#user-content-slonik-utilities-usage-upsert)\n\n\n\u003ca name=\"user-content-slonik-utilities-usage\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage\"\u003e\u003c/a\u003e\n## Usage\n\n\u003ca name=\"user-content-slonik-utilities-usage-update\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-update\"\u003e\u003c/a\u003e\n### \u003ccode\u003eupdate\u003c/code\u003e\n\n```js\nimport {\n  update\n} from 'slonik-utilities';\n\n/**\n * @param connection Instance of Slonik connection.\n * @param {string} tableName Target table name.\n * @param {Object.\u003cstring, ValueExpression\u003e} namedValueBindings Object describing the desired column values.\n * @param {Object.\u003cstring, EqualPredicate\u003e} [booleanExpressionValues] Object describing the boolean expression used to construct WHERE condition.\n * @returns {UpdateResultType}\n */\nupdate;\n\n```\n\nConstructs and executes `UPDATE` query.\n\n\u003ca name=\"user-content-slonik-utilities-usage-update-example-update-all-rows\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-update-example-update-all-rows\"\u003e\u003c/a\u003e\n#### Example: Update all rows\n\nOperation:\n\n```js\nupdate(\n  connection,\n  'user',\n  {\n    givenName: 'foo'\n  }\n);\n\n```\n\nIs equivalent to:\n\n```sql\nUPDATE \"user\"\nSET\n  \"given_name\" = $1;\n\n```\n\n\u003ca name=\"user-content-slonik-utilities-usage-update-example-update-rows-matching-a-boolean-where-condition\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-update-example-update-rows-matching-a-boolean-where-condition\"\u003e\u003c/a\u003e\n#### Example: Update rows matching a boolean WHERE condition\n\nOperation:\n\n```js\nupdate(\n  connection,\n  'user',\n  {\n    givenName: 'foo'\n  },\n  {\n    lastName: 'bar'\n  }\n);\n\n```\n\nIs equivalent to:\n\n```sql\nUPDATE \"user\"\nSET\n  \"given_name\" = $1\nWHERE\n  \"last_name\" = $2;\n\n```\n\n\n\u003ca name=\"user-content-slonik-utilities-usage-updatedistinct\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-updatedistinct\"\u003e\u003c/a\u003e\n### \u003ccode\u003eupdateDistinct\u003c/code\u003e\n\n```js\nimport {\n  updateDistinct\n} from 'slonik-utilities';\n\n/**\n * @param connection Instance of Slonik connection.\n * @param {string} tableName Target table name.\n * @param {Object.\u003cstring, ValueExpression\u003e} namedValueBindings Object describing the desired column values.\n * @param {Object.\u003cstring, EqualPredicate\u003e} [booleanExpressionValues] Object describing the boolean expression used to construct WHERE condition.\n * @returns {UpdateDistinctResultType}\n */\nupdateDistinct;\n\n```\n\nConstructs and executes `UPDATE` query matching only rows with distinct values.\n\n\u003ca name=\"user-content-slonik-utilities-usage-updatedistinct-example-update-all-rows-1\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-updatedistinct-example-update-all-rows-1\"\u003e\u003c/a\u003e\n#### Example: Update all rows\n\nOperation:\n\n```js\nupdate(\n  connection,\n  'user',\n  {\n    givenName: 'foo'\n  }\n);\n\n```\n\nIs equivalent to:\n\n```sql\nUPDATE \"user\"\nSET\n  \"given_name\" = $1\nWHERE\n  \"given_name\" IS DISTINCT FROM $1;\n\n```\n\n\u003ca name=\"user-content-slonik-utilities-usage-updatedistinct-example-update-rows-matching-a-boolean-where-condition-1\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-updatedistinct-example-update-rows-matching-a-boolean-where-condition-1\"\u003e\u003c/a\u003e\n#### Example: Update rows matching a boolean WHERE condition\n\nOperation:\n\n```js\nupdate(\n  connection,\n  'user',\n  {\n    givenName: 'foo'\n  },\n  {\n    lastName: 'bar'\n  }\n);\n\n```\n\nIs equivalent to:\n\n```sql\nUPDATE \"user\"\nSET\n  \"given_name\" = $1\nWHERE\n  \"last_name\" = $2 AND\n  \"given_name\" IS DISTINCT FROM $1;\n\n```\n\n\n\u003ca name=\"user-content-slonik-utilities-usage-upsert\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-upsert\"\u003e\u003c/a\u003e\n### \u003ccode\u003eupsert\u003c/code\u003e\n\n```js\nimport {\n  upsert\n} from 'slonik-utilities';\n\n/**\n * @typedef Configuration~Upsert\n * @property identifierName column name. Default: \"id\".\n */\n\n/**\n * @param connection Instance of Slonik connection.\n * @param {string} tableName Target table name.\n * @param {Object.\u003cstring, ValueExpression\u003e} namedValueBindings Object describing the desired column values.\n * @param {string[]} [uniqueConstraintColumnNames] Names of columns that describe a unique constraint on the table. Defaults to property names of `namedValueBindings`.\n * @param {Configuration~Upsert} [configuration]\n */\nupsert;\n\n```\n\nInserts a new record to the database. If there is a conflicting unique constraint, updates the existing row.\n\n\u003ca name=\"user-content-slonik-utilities-usage-upsert-example-named-value-bindings-equal-to-the-unique-constraint-column-names\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-upsert-example-named-value-bindings-equal-to-the-unique-constraint-column-names\"\u003e\u003c/a\u003e\n#### Example: Named value bindings equal to the unique constraint column names\n\nTable schema:\n\n```sql\nCREATE TABLE user (\n  id SERIAL PRIMARY KEY,\n  email_address text NOT NULL\n);\n\nCREATE UNIQUE INDEX user_email_idx ON user(email_address text_ops);\n\n```\n\nOperation:\n\n```js\nupsert(\n  connection,\n  'user',\n  {\n    emailAddress: 'gajus@gajus.com'\n  }\n);\n\n```\n\nBehaviour:\n\nIf `user` table already contains a record describing the input email, then the following query will be evaluted:\n\n```sql\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1\n);\n\n```\n\nIf `user` table does not contain a record describing the input email, then the following queries will be evaluated:\n\n```sql\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1\n);\n\nINSERT INTO \"user\" (\"email_address\")\nVALUES ($1)\nON CONFLICT (\"email_address\")\nDO NOTHING\nRETURNING \"id\";\n\n-- This query will not be evaluted if the preceeding query returns result.\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1\n);\n\n```\n\n\n\u003ca name=\"user-content-slonik-utilities-usage-upsert-example-named-value-bindings-different-than-the-unique-constraint-column-names\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-upsert-example-named-value-bindings-different-than-the-unique-constraint-column-names\"\u003e\u003c/a\u003e\n#### Example: Named value bindings different than the unique constraint column names\n\nTable schema:\n\n```sql\nCREATE TABLE user (\n  id SERIAL PRIMARY KEY,\n  email_address text NOT NULL,\n  password text NOT NULL,\n  given_name text NOT NULL,\n  family_name text NOT NULL\n);\n\nCREATE UNIQUE INDEX user_email_idx ON user(email_address text_ops);\n\n```\n\nOperation:\n\n```js\nupsert(\n  connection,\n  'user',\n  {\n    emailAddress: 'gajus@gajus.com',\n    familyName: 'Kuizinas',\n    givenName: 'Gajus'\n  },\n  [\n    'email_address'\n  ]\n);\n\n```\n\nBehaviour:\n\nIf `user` table already contains a record describing the input email, then the following query will be evaluted:\n\n```sql\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1 AND\n  \"family_name\" = $2 AND\n  \"given_name\" = $3\n);\n\n```\n\nIf `user` table does not contain a record describing the input email, then the following queries will be evaluated:\n\n```sql\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1 AND\n  \"family_name\" = $2 AND\n  \"given_name\" = $3\n);\n\nINSERT INTO \"user\" (\"email_address\", \"family_name\", \"given_name\")\nVALUES ($1, $2, $3)\nON CONFLICT (\"email_address\")\nDO UPDATE SET\n  \"family_name\" = \"excluded\".\"family_name\",\n  \"given_name\" = \"excluded\".\"given_name\"\nRETURNING \"id\"\n\n```\n\n\u003ca name=\"user-content-slonik-utilities-usage-upsert-example-sql-tags-as-values\"\u003e\u003c/a\u003e\n\u003ca name=\"slonik-utilities-usage-upsert-example-sql-tags-as-values\"\u003e\u003c/a\u003e\n#### Example: SQL tags as values\n\nNamed value binding values can be SQL tokens, e.g.\n\n```js\nupsert(\n  connection,\n  'user',\n  {\n    emailAddress: 'gajus@gajus.com',\n    createdAt: sql.raw('to_timestamp($1)', [1555595070])\n  }\n);\n\n```\n\nGiven the above example, queries equivalent to the following will be evaluated:\n\n```sql\nSELECT \"id\"\nFROM \"user\"\nWHERE (\n  \"email_address\" = $1 AND\n  \"created_at\" = to_timestamp($2)\n);\n\n-- ...\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgajus%2Fslonik-utilities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgajus%2Fslonik-utilities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgajus%2Fslonik-utilities/lists"}