Skip to content

Adds query to transaction and refactor transaction to reuse the get etc functions #102

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

Open
wants to merge 14 commits into
base: v8
Choose a base branch
from
26 changes: 23 additions & 3 deletions src/get/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import adaptor from '../adaptor'
import adaptor, { Adaptor } from '../adaptor'
import type { Collection } from '../collection'
import { wrapData } from '../data'
import { AnyDoc, doc, Doc } from '../doc'
Expand Down Expand Up @@ -76,6 +76,25 @@ export async function get<
ServerTimestamps
> | null> {
const a = await adaptor()
return getCommon(collectionOrRef, maybeIdOrOptions, maybeOptions, {a, t: undefined})
}


export async function getCommon<
Model,
Environment extends RuntimeEnvironment | undefined,
ServerTimestamps extends ServerTimestampsStrategy
>(
collectionOrRef: Collection<Model> | Ref<Model>,
maybeIdOrOptions: string | GetOptions<Environment, ServerTimestamps> | undefined,
maybeOptions: GetOptions<Environment, ServerTimestamps> | undefined,
{a, t}: {a: Adaptor, t: FirebaseFirestore.Transaction | undefined}
): Promise<AnyDoc<
Model,
RuntimeEnvironment,
boolean,
ServerTimestamps
> | null> {
let collection: Collection<Model>
let id: string
let options: GetOptions<Environment, ServerTimestamps> | undefined
Expand All @@ -93,10 +112,11 @@ export async function get<
| undefined
}

assertEnvironment(a, options?.assertEnvironment)
if (!t)
assertEnvironment(a, options?.assertEnvironment)

const firestoreDoc = a.firestore.collection(collection.path).doc(id)
const firestoreSnap = await firestoreDoc.get()
const firestoreSnap = await (t ? t.get(firestoreDoc) : firestoreDoc.get())
const firestoreData = a.getDocData(firestoreSnap, options)
const data = firestoreData && (wrapData(a, firestoreData) as Model)
return data
Expand Down
22 changes: 19 additions & 3 deletions src/query/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import adaptor from '../adaptor'
import adaptor, { Adaptor } from '../adaptor'
import type { Collection } from '../collection'
import type { Cursor, CursorMethod } from '../cursor'
import { unwrapData, wrapData } from '../data'
Expand Down Expand Up @@ -60,8 +60,23 @@ export async function query<
options?: QueryOptions<Environment, ServerTimestamps>
): Promise<AnyDoc<Model, Environment, boolean, ServerTimestamps>[]> {
const a = await adaptor()
return queryCommon(collection, queries, options, {a, t: undefined})
}

assertEnvironment(a, options?.assertEnvironment)

export async function queryCommon<
Model,
Environment extends RuntimeEnvironment | undefined,
ServerTimestamps extends ServerTimestampsStrategy
>(
collection: Collection<Model> | CollectionGroup<Model>,
queries: Query<Model, keyof Model>[],
options: QueryOptions<Environment, ServerTimestamps> | undefined,
{a, t}: {a: Adaptor, t: FirebaseFirestore.Transaction | undefined}
): Promise<AnyDoc<Model, Environment, boolean, ServerTimestamps>[]> {

if (!t)
assertEnvironment(a, options?.assertEnvironment)

const { firestoreQuery, cursors } = queries.reduce(
(acc, q) => {
Expand Down Expand Up @@ -144,7 +159,7 @@ export async function query<
}, firestoreQuery)
: firestoreQuery

const firebaseSnap = await paginatedFirestoreQuery.get()
const firebaseSnap = await (t ? t.get(paginatedFirestoreQuery) : paginatedFirestoreQuery.get())

return firebaseSnap.docs.map((snap) =>
doc(
Expand All @@ -160,3 +175,4 @@ export async function query<
)
)
}

49 changes: 9 additions & 40 deletions src/transaction/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { get, getCommon, GetOptions, query, queryCommon } from '..';
import adaptor from '../adaptor'
import type { Collection } from '../collection'
import { unwrapData, wrapData } from '../data'
import { AnyDoc, doc } from '../doc'
import { AnyDoc, doc, Doc } from '../doc'
import type { Field } from '../field'
import { Ref, ref } from '../ref'
import type {
Expand All @@ -15,6 +16,8 @@ import type { UpdateModel } from '../update'
import type { UpsetModel } from '../upset'
import { assertEnvironment } from '../_lib/assertEnvironment'



/**
* The transaction read API object. It contains {@link TransactionRead.get|get}
* the function that allows reading documents from the database.
Expand Down Expand Up @@ -54,6 +57,7 @@ export interface TransactionRead<Environment extends RuntimeEnvironment> {
id: string,
options?: DocOptions<ServerTimestamps>
): Promise<AnyDoc<Model, Environment, boolean, ServerTimestamps> | null>
query: typeof query
}

/**
Expand Down Expand Up @@ -281,44 +285,6 @@ export async function transaction<
assertEnvironment(a, options?.assertEnvironment)

return a.firestore.runTransaction((t) => {
async function get<
Model,
ServerTimestamps extends ServerTimestampsStrategy
>(
collectionOrRef: Collection<Model> | Ref<Model>,
maybeIdOrOptions?: string | DocOptions<ServerTimestamps>,
maybeOptions?: DocOptions<ServerTimestamps>
): Promise<AnyDoc<Model, Environment, boolean, ServerTimestamps> | null> {
let collection: Collection<Model>
let id: string
let options: DocOptions<ServerTimestamps> | undefined

if (collectionOrRef.__type__ === 'collection') {
collection = collectionOrRef as Collection<Model>
id = maybeIdOrOptions as string
options = maybeOptions as DocOptions<ServerTimestamps>
} else {
const ref = collectionOrRef as Ref<Model>
collection = ref.collection
id = ref.id
options = maybeIdOrOptions as DocOptions<ServerTimestamps> | undefined
}

const firestoreDoc = a.firestore.collection(collection.path).doc(id)
// ^ above
// TODO: Refactor code above and below because is all the same as in the regular get function
const firestoreSnap = await t.get(firestoreDoc)
// v below
const firestoreData = a.getDocData(firestoreSnap, options)
const data = firestoreData && (wrapData(a, firestoreData) as Model)
return data
? doc(ref(collection, id), data, {
environment: a.environment as Environment,
serverTimestamps: options?.serverTimestamps,
...a.getDocMeta(firestoreSnap)
})
: null
}

function set<Model>(
collectionOrRef: Collection<Model> | Ref<Model>,
Expand Down Expand Up @@ -426,7 +392,10 @@ export async function transaction<
t.delete(firebaseDoc)
}

return readFunction({ get }).then((data) =>
return readFunction({
get: (...props) => (getCommon as any)(props[0], props[1], props[2], {a, t}),
Copy link
Author

Choose a reason for hiding this comment

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

I had to as any because all those generics and overloads of get weren't matching, but it's the same params order. Tried to get it working without the type cast but hadn't success.

Also, I props[0], props[1], props[2] instead of ...props because some of them are optional and would make {a, t} be in the wrong param instead of the forth one.

query: (...props) => queryCommon(props[0], props[1], props[2], {a, t})
}).then((data) =>
writeFunction({ data, set, upset, update, remove })
)
})
Expand Down