-
Notifications
You must be signed in to change notification settings - Fork 17
Firestore implementation #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
e76720c
2d1d43b
fad813e
3f980bd
b3de5b9
cf8541c
ffe593c
1127fe9
60ed5ce
4a1ad05
f0860df
fdc7a73
5e9a1eb
0385b90
faa94f5
55566aa
d8db004
79ee3c5
0bb71e2
0b6b256
4193b52
f7510a5
0da896f
c3b6fad
04736a5
338d86f
4f56d4e
c218973
dfd6aa7
3505047
e584b9d
0810eed
04ac252
6dc26ff
93ecbb8
5c0c047
c4d2a9a
22e9876
ec05b84
58d25ab
e135d0e
1e794ef
2c36ee8
2ce9a28
03df72a
37fab7b
393ffb3
b09a50e
15caebd
db627bc
8a95336
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// const { recordSetToObj, escapeId, patchFieldName, unpatchFieldName } = require('./spanner_utils') | ||
const { Timestamp } = require('@google-cloud/firestore') | ||
const { SystemFields } = require('velo-external-db-commons') | ||
|
||
class DataProvider { | ||
|
@@ -8,118 +8,87 @@ class DataProvider { | |
this.database = database | ||
} | ||
|
||
// async find(collectionName, filter, sort, skip, limit) { | ||
// const {filterExpr, parameters} = this.filterParser.transform(filter) | ||
// const { sortExpr } = this.filterParser.orderBy(sort) | ||
// | ||
// const query = { | ||
// sql: `SELECT * FROM ${escapeId(collectionName)} ${filterExpr} ${sortExpr} LIMIT @limit OFFSET @skip`, | ||
// params: { | ||
// skip: skip, | ||
// limit: limit, | ||
// }, | ||
// } | ||
// Object.assign(query.params, parameters) | ||
// | ||
// const [rows] = await this.database.run(query); | ||
// return recordSetToObj(rows).map( this.asEntity.bind(this) ) | ||
// } | ||
// | ||
// async count(collectionName, filter) { | ||
// const {filterExpr, parameters} = this.filterParser.transform(filter) | ||
// const query = { | ||
// sql: `SELECT COUNT(*) AS num FROM ${escapeId(collectionName)} ${filterExpr}`.trim(), | ||
// params: { }, | ||
// }; | ||
// Object.assign(query.params, parameters) | ||
// | ||
// const [rows] = await this.database.run(query) | ||
// const objs = recordSetToObj(rows).map( this.asEntity.bind(this) ) | ||
// | ||
// return objs[0].num; | ||
// } | ||
// | ||
// async insert(collectionName, items) { | ||
// await this.database.table(collectionName) | ||
// .insert(items.map(this.asDBEntity.bind(this))) | ||
// return items.length | ||
// } | ||
// | ||
// asDBEntity(item) { | ||
// return Object.keys(item) | ||
// .reduce((obj, key) => { | ||
// return { ...obj, [patchFieldName(key)]: item[key] } | ||
// }, {}) | ||
// } | ||
// | ||
// fixDates(value) { | ||
// if (value instanceof Date) { | ||
// // todo: fix this hack !!! | ||
// const date = value.toISOString() | ||
// const date2 = `${date.substring(0, date.lastIndexOf('.') + 4)}${date.slice(-1)}` | ||
// return new Date(date2) | ||
// } | ||
// return value | ||
// | ||
// } | ||
// | ||
// asEntity(dbEntity) { | ||
// return Object.keys(dbEntity) | ||
// .reduce(function (obj, key) { | ||
// return { ...obj, [unpatchFieldName(key)]: this.fixDates(dbEntity[key]) } | ||
// }.bind(this), {}) | ||
// } | ||
// | ||
// async update(collectionName, items) { | ||
// const item = items[0] | ||
// const systemFieldNames = SystemFields.map(f => f.name) | ||
// const updateFields = Object.keys(item).filter( k => !systemFieldNames.includes(k) ) | ||
// | ||
// if (updateFields.length === 0) { | ||
// return 0 | ||
// } | ||
// | ||
// await this.database.table(collectionName) | ||
// .update(items.map( this.asDBEntity.bind(this) )) | ||
// return items.length | ||
// } | ||
// | ||
// async delete(collectionName, itemIds) { | ||
// await this.database.table(collectionName) | ||
// .deleteRows(itemIds) | ||
// return itemIds.length | ||
// } | ||
// | ||
// async truncate(collectionName) { | ||
// // todo: properly implement this | ||
// const query = { | ||
// sql: `SELECT * FROM ${escapeId(collectionName)} LIMIT @limit OFFSET @skip`, | ||
// params: { | ||
// skip: 0, | ||
// limit: 1000, | ||
// }, | ||
// } | ||
// | ||
// const [rows] = await this.database.run(query); | ||
// const itemIds = recordSetToObj(rows).map( this.asEntity.bind(this) ).map(e => e._id) | ||
// | ||
// await this.delete(collectionName, itemIds) | ||
// } | ||
// | ||
// async aggregate(collectionName, filter, aggregation) { | ||
// const {filterExpr: whereFilterExpr, parameters: whereParameters} = this.filterParser.transform(filter) | ||
// const {fieldsStatement, groupByColumns, havingFilter, parameters} = this.filterParser.parseAggregation(aggregation.processingStep, aggregation.postFilteringStep) | ||
// | ||
// const query = { | ||
// sql: `SELECT ${fieldsStatement} FROM ${escapeId(collectionName)} ${whereFilterExpr} GROUP BY ${groupByColumns.map( escapeId ).join(', ')} ${havingFilter}`, | ||
// params: { }, | ||
// } | ||
// | ||
// Object.assign(query.params, whereParameters, parameters) | ||
// | ||
// const [rows] = await this.database.run(query) | ||
// return recordSetToObj(rows).map( this.asEntity.bind(this) ) | ||
// } | ||
async find(collectionName, filter, sort, skip, limit) { | ||
const filterOperations = this.filterParser.transform(filter) | ||
const sortOperations = this.filterParser.orderBy(sort) | ||
|
||
let collectionRef = this.database.collection(collectionName) | ||
|
||
filterOperations.forEach(filterOp => collectionRef.where(filterOp.fieldName,filterOp.opStr,filterOp.value)) | ||
|
||
sortOperations.forEach(sortOp => collectionRef = collectionRef.orderBy(sortOp.fieldName,sortOp.direction)) | ||
|
||
noam-almog marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const docs = (await collectionRef.limit(limit).get()).docs | ||
|
||
return docs.map(doc => this.asEntity(doc)) | ||
} | ||
|
||
async count(collectionName, filter) { | ||
const filterOperations = this.filterParser.transform(filter) | ||
const collectionRef = this.database.collection(collectionName) | ||
|
||
filterOperations.forEach( filterOp => collectionRef.where(filterOp.fieldName,filterOp.opStr,filterOp.value)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix to reduce There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and spaces after ',' (again) |
||
|
||
return (await collectionRef.get()).size | ||
} | ||
|
||
async insert(collectionName, items) { | ||
const batch = this.database.batch() | ||
|
||
items.forEach( item => batch.set(this.database.doc(`${collectionName}/${item._id}`),item)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reduce |
||
|
||
return (await batch.commit()).length | ||
} | ||
|
||
fixDates(value) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extract those two function to another file, utils perhaps ? |
||
if (value instanceof Timestamp) { | ||
return value.toDate() | ||
} | ||
return value | ||
} | ||
|
||
asEntity(docEntity) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extract |
||
const doc = docEntity.data() | ||
return Object.keys(doc) | ||
.reduce(function (obj, key) { | ||
return { ...obj, [key]: this.fixDates(doc[key]) } | ||
}.bind(this), {}) | ||
} | ||
|
||
async update(collectionName, items) { | ||
const item = items[0] | ||
const batch = this.database.batch() | ||
const systemFieldNames = SystemFields.map(f => f.name) | ||
const updateFields = Object.keys(item).filter( k => !systemFieldNames.includes(k) ) | ||
|
||
if (updateFields.length === 0) { | ||
return 0 | ||
} | ||
|
||
items.forEach( item => | ||
batch.update(this.database.doc(`${collectionName}/${item._id}`),item)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space after ',' |
||
|
||
return (await batch.commit()).length | ||
} | ||
|
||
async delete(collectionName, itemIds) { | ||
const batch = this.database.batch() | ||
itemIds.forEach( itemId => batch.delete(this.database.doc(`${collectionName}/${itemId}`)) ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to reduce |
||
|
||
return (await batch.commit()).length | ||
} | ||
|
||
async truncate(collectionName) { | ||
noam-almog marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const snapshot = await this.database.collection(collectionName).get() | ||
|
||
if(snapshot.size === 0){ | ||
return 0 | ||
} | ||
|
||
const itemIds = snapshot.docs.map((doc) => (doc.data())._id ); | ||
return await this.delete(collectionName, itemIds) | ||
} | ||
|
||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add space after ','