Skip to content

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

Merged
merged 51 commits into from
Sep 9, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e76720c
added some filter transformer functions
MXPOL Sep 1, 2021
2d1d43b
Merge branch 'master' into firestore-implementation
MXPOL Sep 2, 2021
fad813e
firestore data provider implemenation
MXPOL Sep 5, 2021
3f980bd
minor changes to data provider
MXPOL Sep 5, 2021
b3de5b9
firestore filter implementaion
MXPOL Sep 9, 2021
cf8541c
firestores data drovider refactor
MXPOL Sep 9, 2021
ffe593c
nop
MXPOL Sep 9, 2021
1127fe9
github actions (#27)
Idokah Sep 5, 2021
60ed5ce
split engine to impl, npm t will run all tests but it's possible to t…
noam-almog Sep 5, 2021
4a1ad05
e2e refactor
noam-almog Sep 5, 2021
f0860df
e2e refactor
noam-almog Sep 5, 2021
fdc7a73
Azure adapter installer (#19)
Idokah Sep 5, 2021
5e9a1eb
remove travis.yml
Idokah Sep 5, 2021
0385b90
e2e refactor
noam-almog Sep 5, 2021
faa94f5
refactor mysql test env
noam-almog Sep 5, 2021
55566aa
refactor postgres test env
noam-almog Sep 5, 2021
d8db004
refactor spanner test env
noam-almog Sep 5, 2021
79ee3c5
refactor sql server test env
noam-almog Sep 5, 2021
0bb71e2
reduce deps on main module
noam-almog Sep 5, 2021
0b6b256
dead code
noam-almog Sep 5, 2021
4193b52
added mongo to docker compose
noam-almog Sep 5, 2021
f7510a5
debugging mysql build on github
noam-almog Sep 5, 2021
0da896f
github action, changed docker pre pull of images
noam-almog Sep 5, 2021
c3b6fad
docker compose fixes
noam-almog Sep 5, 2021
04736a5
debugging github actions
noam-almog Sep 5, 2021
338d86f
fixed warning
noam-almog Sep 5, 2021
4f56d4e
debug error
noam-almog Sep 5, 2021
c218973
debug github build
noam-almog Sep 5, 2021
dfd6aa7
fixed postgres error on ci
noam-almog Sep 5, 2021
3505047
partial fix for build on CI
noam-almog Sep 5, 2021
e584b9d
adding spanner to CI
noam-almog Sep 5, 2021
0810eed
split CI build task to all code and build target for each integration
noam-almog Sep 5, 2021
04ac252
added CI target for spanner
noam-almog Sep 5, 2021
6dc26ff
added CI target for mySql and sql server
noam-almog Sep 5, 2021
93ecbb8
added CI target for mySql and sql server
noam-almog Sep 5, 2021
5c0c047
split ci to main target and each engine target
noam-almog Sep 5, 2021
c4d2a9a
split ci to main target and each engine target
noam-almog Sep 5, 2021
22e9876
fixed warning
noam-almog Sep 5, 2021
ec05b84
adding firestore to tests
noam-almog Sep 5, 2021
58d25ab
renamed target
noam-almog Sep 5, 2021
e135d0e
removed comments
noam-almog Sep 5, 2021
1e794ef
added eslint config file
MXPOL Sep 9, 2021
2c36ee8
consolidate install scripts
noam-almog Sep 9, 2021
2ce9a28
fix mssql connection provider (#28)
Idokah Sep 9, 2021
03df72a
initial mongo template
noam-almog Sep 9, 2021
37fab7b
renamed main module src dir from src to lib
noam-almog Sep 9, 2021
393ffb3
eslint config file - ignore test files
MXPOL Sep 9, 2021
b09a50e
Merge branch 'master' into firestore-implementation
MXPOL Sep 9, 2021
15caebd
fix lint problems
MXPOL Sep 9, 2021
db627bc
firestores data provider functions refactor
MXPOL Sep 9, 2021
8a95336
filter transformer improvements
MXPOL Sep 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/external-db-firestore/lib/connection_provider.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const SchemaProvider = require('./firestore_schema_provider')
const DataProvider = require('./firestore_data_provider')
// const FilterParser = require('./sql_filter_transformer')
const FilterParser = require('./sql_filter_transformer')
const DatabaseOperations = require('./firestore_operations')
const Firestore = require('@google-cloud/firestore');

Expand All @@ -11,8 +11,8 @@ const init = ([projectId]) => {

const databaseOperations = new DatabaseOperations(firestore)

// const filterParser = new FilterParser()
const dataProvider = new DataProvider(firestore)
const filterParser = new FilterParser()
const dataProvider = new DataProvider(firestore,filterParser)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space after ','

const schemaProvider = new SchemaProvider(firestore)

return { dataProvider, schemaProvider, databaseOperations, connection: firestore, cleanup: async () => await firestore.terminate() }
Expand Down
195 changes: 82 additions & 113 deletions packages/external-db-firestore/lib/firestore_data_provider.js
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 {
Expand All @@ -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))


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))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix to reduce

Copy link
Collaborator

Choose a reason for hiding this comment

The 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reduce


return (await batch.commit()).length
}

fixDates(value) {
Copy link
Collaborator

Choose a reason for hiding this comment

The 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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after ','
shouldn't the forEach be a map or reduce here ?


return (await batch.commit()).length
}

async delete(collectionName, itemIds) {
const batch = this.database.batch()
itemIds.forEach( itemId => batch.delete(this.database.doc(`${collectionName}/${itemId}`)) )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to reduce


return (await batch.commit()).length
}

async truncate(collectionName) {
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)
}

}

Expand Down
16 changes: 8 additions & 8 deletions packages/external-db-firestore/lib/firestore_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
// return f
// }
//
// const testLiteral = s => /^[a-zA-Z_0-9_]+$/.test(s)
// const validateLiteral = l => {
// if (!testLiteral(l)) {
// throw new InvalidQuery(`Invalid literal`)
// }
// return `@${l}`
// }
const testLiteral = s => /^[a-zA-Z_0-9_]+$/.test(s)
const validateLiteral = l => {
if (!testLiteral(l)) {
throw new InvalidQuery(`Invalid literal`)
}
return `@${l}`
}

module.exports = { /*recordSetToObj, escapeId, patchFieldName, unpatchFieldName, testLiteral, validateLiteral*/ }
module.exports = { /*recordSetToObj, escapeId, patchFieldName, unpatchFieldName,*/ testLiteral, validateLiteral }
Loading