Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@knorm/postgres

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@knorm/postgres - npm Package Compare versions

Comparing version 1.1.2 to 1.2.0

74

lib/KnormPostgres.js

@@ -61,5 +61,8 @@ const { Knorm } = require('@knorm/knorm');

knorm.Field = knorm.Model.Field = class PostgresField extends Field {
// TODO: auto-cast decimal fields from string on fetch
// TODO: v2: auto-cast decimal fields from string on fetch
cast(value, modelInstance, options) {
if (this.type !== 'json' && this.type !== 'jsonb') {
if (
(this.type !== 'json' && this.type !== 'jsonb') ||
value instanceof knorm.Query.prototype.sql
) {
return super.cast(value, modelInstance, options);

@@ -303,2 +306,6 @@ }

patch(patch = true) {
return this.setOption('patch', patch);
}
quote(value) {

@@ -338,2 +345,65 @@ return `"${value}"`;

// TODO: strict mode: warn/throw if a patch field is invalid
// TODO: strict mode: warn/throw if a patch field is not a json(b) field
isPatchedField(field) {
field = this.config.fields[field];
if (field.type !== 'json' && field.type !== 'jsonb') {
return false;
}
const { patch } = this.options;
if (patch === true) {
return true;
}
const fields = Array.isArray(patch) ? patch : [patch];
return fields.includes(field.name);
}
getCastFields(fields, { forInsert, forUpdate }) {
if (forInsert || (forUpdate && !this.options.patch)) {
return fields;
}
return fields.filter(field => !this.isPatchedField(field));
}
getRowValue({ field, column, value }, { forInsert, forUpdate }) {
if (
forInsert ||
value instanceof this.sql ||
(forUpdate && !this.options.patch) ||
!this.isPatchedField(field)
) {
return value;
}
if (Array.isArray(value) || typeof value !== 'object') {
throw new this.constructor.QueryError(
`${
this.model.name
}: cannot patch field \`${field}\` (JSON patching is only supported for objects)`
);
}
const isJson = this.config.fields[field].type === 'json';
let patch = isJson ? `${column}::jsonb` : column;
Object.entries(value).forEach(([key, value]) => {
patch = `jsonb_set(${patch}, '{${key}}', '${JSON.stringify(value)}')`;
});
if (isJson) {
patch = `${patch}::json`;
}
return this.sql(patch);
}
// TODO: support using column names in the raw sql for multi-updates
// TODO: document the "v" alias used in the multi-update query or allow it
// to be configurable
// TODO: v2: refactor prepareUpdateBatch => getUpdateBatch
// TODO: throw if the update is empty (after excluding notUpdated). otherwise

@@ -340,0 +410,0 @@ // it ends up being a hard-to-debug sql syntax error

16

package.json
{
"name": "@knorm/postgres",
"version": "1.1.2",
"version": "1.2.0",
"description": "Postgres plugin for knorm",

@@ -19,17 +19,17 @@ "main": "index.js",

"peerDependencies": {
"@knorm/knorm": "^1.3.0",
"@knorm/relations": "^1.1.3"
"@knorm/knorm": "^1.7.0",
"@knorm/relations": "^1.2.3"
},
"devDependencies": {
"@knorm/knorm": "^1.3.0",
"@knorm/relations": "^1.1.3",
"@knorm/knorm": "^1.7.0",
"@knorm/relations": "^1.2.3",
"coveralls": "^3.0.0",
"eslint": "^4.15.0",
"eslint-config-ganintegrity": "^2.0.2",
"knex": "^0.14.6",
"knex": "^0.15.0",
"mocha": "^5.1.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.4.1",
"nyc": "^12.0.1",
"prettier": "^1.10.2",
"sinon": "^5.0.7",
"sinon": "^6.0.0",
"unexpected": "^10.37.7",

@@ -36,0 +36,0 @@ "unexpected-knex": "^1.2.1",

@@ -31,3 +31,3 @@ # @knorm/postgres

## Usage
## Initialization

@@ -55,3 +55,87 @@ ```js

| `restoreClient` | (async) function | a function called before a client is released back into the pool. useful for restoring a client e.g. unsetting session variables. it's called with the client as the only argument |
NOTE that all options are optional.
NOTE that all options are optional.
## Usage
### JSON patching
When updating `json` and `jsonb` fields, you may wish to only update part of the
JSON data instead of the whole object. You can partially update json fields via
the `patch` option:
* set the option value to `true` to patch all the json and jsonb fields in the
update data
* set the option value to a string field-name to patch a single field in the
update data
* set the option value to an array of field-names to patch a multiple fields
in the update data
For example:
```js
class User extends Model {}
User.fields = {
id: { type: 'integer' },
jsonb: { type: 'jsonb' },
json: { type: 'json' }
};
const data = { jsonb: { foo: 'bar' }, json: { foo: 'bar' } };
// to update whole object without patching:
User.update(data);
// to patch all fields in the update:
User.update(data, { patch: true });
// to patch a single field:
User.update(data, { patch: 'json' });
// to patch multiple fields:
User.update(data, { patch: ['json', 'jsonb'] });
```
Note that only basic json-patching is supported: only the first level of patching
is supported. For instance, nested objects or array values cannot be patched since
@knorm/postgres cannot figure out if the intention is patch the object/array or
to replace it entirely:
```js
// assuming the data is currently:
new User({
jsonb: { top: { foo: 'foo' } },
json: { top: { foo: 'foo' } }
});
// is the intention here to add a new `bar` key to the `top` object or to replace
// the `top` key with the value `{ bar: 'bar' }`?
User.query
.patch(['json', 'jsonb'])
.update({
jsonb: { top: { bar: 'bar' } },
json: { top: { bar: 'bar' } },
});
```
For complex patching, use
[jsonb_set](https://www.postgresql.org/docs/9.5/static/functions-json.html)
directly in a raw-sql update:
```js
// to add a nested `bar` key/value:
User.query
.patch(['json', 'jsonb'])
.update({
jsonb: User.query.sql(`jsonb_set("jsonb", '{top,bar}', '"bar"')`),
// for json field-types, you have to cast to jsonb and then cast the result
// back to json
json: User.query.sql(`jsonb_set("json"::jsonb, '{top,bar}', '"bar"')::json`)
});
// result:
new User({
jsonb: { top: { foo: 'foo', bar: 'bar' } },
json: { top: { foo: 'foo', bar: 'bar' } }
});
```

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc