djorm-db-gcp-datastore
Advanced tools
Comparing version 0.1.12-alpha.1 to 0.1.13-alpha.0
@@ -0,12 +1,16 @@ | ||
const { ComparisonOperator } = require('djorm/db/ComparisonOperator') | ||
const { Count } = require('djorm/db/Count') | ||
const { DatastoreFormatterBase } = require('./DatastoreFormatterBase') | ||
const { Delete } = require('djorm/db/Delete') | ||
const { Insert } = require('djorm/db/Insert') | ||
const { NotImplemented } = require('djorm/errors') | ||
const { QueryFormatterError } = require('djorm/db/errors') | ||
const { QueryFormatter } = require('djorm/db/QueryFormatter') | ||
const { Select } = require('djorm/db/Select') | ||
const { Update } = require('djorm/db/Update') | ||
class DatastoreFormatter extends QueryFormatter { | ||
class DatastoreFormatter extends DatastoreFormatterBase { | ||
constructor (driver) { | ||
super() | ||
this.driver = driver | ||
this.mapOrderBy = this.mapOrderBy.bind(this) | ||
} | ||
@@ -17,18 +21,154 @@ | ||
formatQuery (qs) { | ||
if (qs instanceof Select) { | ||
return this.requireFormatter('DatastoreSelectFormatter').formatQuery(qs) | ||
if (qs instanceof Delete) { | ||
return this.formatDelete(qs) | ||
} | ||
if (qs instanceof Insert) { | ||
return this.requireFormatter('DatastoreInsertFormatter').formatQuery(qs) | ||
return this.formatInsert(qs) | ||
} | ||
if (qs instanceof Select) { | ||
return this.formatSelect(qs) | ||
} | ||
if (qs instanceof Update) { | ||
return this.requireFormatter('DatastoreUpdateFormatter').formatQuery(qs) | ||
return this.formatUpdate(qs) | ||
} | ||
throw new QueryFormatterError('Unknown query type') | ||
} | ||
formatDelete (qs) { | ||
return async () => { | ||
await this.driver.waitForConnection() | ||
await this.db.delete(this.mapFilter(qs, { qs })) | ||
} | ||
} | ||
formatInsert (qs) { | ||
return async () => { | ||
await this.driver.waitForConnection() | ||
const values = await this.prepareKeys(qs, this.formatValues(qs)) | ||
await this.db.upsert(values) | ||
const last = values[values.length - 1] | ||
return { | ||
insertId: this.getKeyValue(last) | ||
} | ||
} | ||
} | ||
formatSelect (qs) { | ||
return () => { | ||
const [query, modifiers] = this.getSelectModifiers(qs) | ||
const dsQuery = modifiers.reduce( | ||
(aggr, modifier) => modifier(qs, aggr), | ||
query | ||
) | ||
const count = qs.props.selection.find(item => item instanceof Count) | ||
// @HACK: Assume this is count query and add dummy postprocessor | ||
if (count) { | ||
const dsq = dsQuery | ||
.select('__key__') | ||
.limit(-1) | ||
.offset(0) | ||
dsq.postprocess = results => [ | ||
{ | ||
__djorm_cnt: results.length | ||
} | ||
] | ||
return dsq | ||
} | ||
return dsQuery | ||
} | ||
} | ||
formatUpdate (qs) { | ||
return async () => { | ||
await this.driver.waitForConnection() | ||
const [result] = await this.db.upsert(this.formatValues(qs)) | ||
return { | ||
changes: result.indexUpdates | ||
} | ||
} | ||
} | ||
async prepareKeys (qs, values) { | ||
const keyLess = values.filter(item => !this.getKeyValue(item)) | ||
const partialKey = this.formatKey(qs.props.model) | ||
const [ids] = await this.db.allocateIds(partialKey, keyLess.length) | ||
return values.map(item => | ||
this.getKeyValue(item) | ||
? item | ||
: { | ||
...item, | ||
key: ids.shift() | ||
} | ||
) | ||
} | ||
getSelectModifiers (qs) { | ||
const modifiers = [ | ||
this.mapFilter, | ||
this.mapOrderBy, | ||
this.mapLimit, | ||
this.mapOffset | ||
] | ||
const query = this.db.createQuery(this.db.namespace, qs.props.target) | ||
return [query, modifiers] | ||
} | ||
mapCondition (qs, ...args) { | ||
if (qs instanceof Select) { | ||
return this.mapSelectCondition(qs, ...args) | ||
} | ||
if (qs instanceof Delete) { | ||
return this.requireFormatter('DatastoreDeleteFormatter').formatQuery(qs) | ||
return this.mapDeleteCondition(qs, ...args) | ||
} | ||
throw new QueryFormatterError('Unknown query type') | ||
throw new NotImplemented( | ||
`Cannot properly map query conditions for "${qs.constructor.name}" query ` | ||
) | ||
} | ||
mapDeleteCondition (qs, query, fieldName, operator, value) { | ||
if (operator !== ComparisonOperator.eq) { | ||
throw new NotImplemented( | ||
'Datastore db support only eq operator for deletion' | ||
) | ||
} | ||
if (fieldName !== query.qs.props.model.pkName) { | ||
throw new NotImplemented( | ||
`Datastore delete can filter only by primary keys, but "${fieldName}" was given` | ||
) | ||
} | ||
return this.formatKey(query.qs.props.model, value) | ||
} | ||
mapSelectCondition (qs, query, fieldName, operator, value) { | ||
if (qs.model && qs.model.pkName === fieldName) { | ||
return query.filter('__key__', operator, this.formatKey(qs.model, value)) | ||
} | ||
return query.filter(fieldName, operator, value) | ||
} | ||
mapOrderByDirective (query, oi) { | ||
const [name, descending] = this.parseOrderDirective(oi) | ||
return query.order(name, { descending }) | ||
} | ||
mapOrderBy (qs, query) { | ||
if (qs.props.orderBy) { | ||
return qs.props.orderBy.reduce( | ||
(q, expr) => this.mapOrderByDirective(q, expr), | ||
query | ||
) | ||
} | ||
return query | ||
} | ||
mapLimit (qs, query) { | ||
return qs.props.limit ? query.limit(qs.props.limit) : query | ||
} | ||
mapOffset (qs, query) { | ||
return qs.props.offset ? query.offset(qs.props.offset) : query | ||
} | ||
} | ||
module.exports = { DatastoreFormatter } |
@@ -21,6 +21,2 @@ const { ComparisonOperator } = require('djorm/db/ComparisonOperator') | ||
getPrimaryKey (qs) { | ||
return qs.model && qs.model.pkName | ||
} | ||
formatKey (model, pk) { | ||
@@ -27,0 +23,0 @@ return this.db.key([model.table, pk]) |
56
index.js
@@ -1,55 +0,1 @@ | ||
const { Database } = require('djorm/db/Database') | ||
const { DatastoreMapper } = require('./DatastoreMapper') | ||
const { DatastoreFormatter } = require('./DatastoreFormatter') | ||
const { Datastore } = require('@google-cloud/datastore') | ||
class DatastoreDatabase extends Database { | ||
db = null | ||
Mapper = DatastoreMapper | ||
Formatter = DatastoreFormatter | ||
get config () { | ||
return { | ||
apiEndpoint: this.props.apiEndpoint, | ||
namespace: this.namespace, | ||
projectId: this.props.projectId, | ||
credentials: { | ||
client_email: this.props.username, | ||
private_key: this.props.password | ||
} | ||
} | ||
} | ||
get namespace () { | ||
return this.props.namespace | ||
} | ||
async connectDb () { | ||
this.db = new Datastore(this.config) | ||
} | ||
async disconnectDb () { | ||
this.db = null | ||
} | ||
async execDb (query) { | ||
return await query() | ||
} | ||
async queryDb (configureQuery) { | ||
const query = configureQuery() | ||
const [result] = await this.db.runQuery(query) | ||
return query.postprocess ? query.postprocess(result) : result | ||
} | ||
formatQuery (qs) { | ||
return new this.Formatter(this).formatQuery(qs) | ||
} | ||
streamDb (qs) { | ||
const createQuery = this.formatQuery(qs) | ||
return createQuery().runStream() | ||
} | ||
} | ||
module.exports = DatastoreDatabase | ||
module.exports = require('./DatastoreDatabase') |
{ | ||
"name": "djorm-db-gcp-datastore", | ||
"version": "0.1.12-alpha.1", | ||
"version": "0.1.13-alpha.0", | ||
"description": "Datastore bindings for djorm", | ||
@@ -20,3 +20,3 @@ "author": "Pavel Žák <pavel@zak.global>", | ||
"@google-cloud/datastore": "^6.3.1", | ||
"djorm": "^0.1.12-alpha.1" | ||
"djorm": "^0.1.13-alpha.0" | ||
}, | ||
@@ -30,3 +30,3 @@ "repository": { | ||
}, | ||
"gitHead": "0a62648edf01e92f4ba57b5a7e39ec6be54ca535" | ||
"gitHead": "1cbe04a1e6110a47f86fe9b2fe2da73922c43a44" | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
12738
353
9
1
+ Addeddjorm@0.1.13-alpha.7(transitive)
- Removeddjorm@0.1.12-alpha.1(transitive)
Updateddjorm@^0.1.13-alpha.0