diff --git a/src/index.ts b/src/index.ts index 16b2a76..f62d85f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,7 +58,12 @@ class Transaction { constructor(queries: Array, options?: TransactionOptions) { const models = options?.models || []; - this.#internalQueries = queries.map((query) => ({ query, selectedFields: [] })); + this.#internalQueries = queries.map((query) => ({ + query, + selectedFields: [], + models: [], + })); + this.#compileQueries(models, options); } @@ -105,18 +110,20 @@ class Transaction { const { for: forInstruction, ...restInstructions } = (queryInstructions || {}) as AllQueryInstructions; - let modelList = modelsWithAttributes; + let modelList = modelsWithPresets.filter((model) => { + return model.slug !== ROOT_MODEL.slug; + }); // If a `for` instruction was provided, that means we only want to select the // related models of the model that was provided in `for`, instead of selecting // all models at once. if (forInstruction) { - const mainModel = getModelBySlug(modelsWithAttributes, forInstruction); + const mainModel = getModelBySlug(modelList, forInstruction); modelList = Object.values(mainModel.fields || {}) .filter((field) => field.type === 'link') .map((field) => { - return modelsWithAttributes.find( + return modelList.find( (model) => model.slug === field.target, ) as PrivateModel; }); @@ -124,9 +131,7 @@ class Transaction { // Track which models are being addressed by the query, in order to ensure that // its results are being formatted correctly. - this.#internalQueries[index].affectedModels = modelList.map( - (model) => model.slug, - ); + this.#internalQueries[index].models = modelList; return modelList.map((model) => { const query: Query = { @@ -141,7 +146,7 @@ class Transaction { }); for (const { query, index } of expandedQueries) { - const { dependencies, main, selectedFields } = compileQueryInput( + const { dependencies, main, selectedFields, model } = compileQueryInput( query, modelsWithPresets, options?.inlineParams ? null : [], @@ -168,6 +173,10 @@ class Transaction { // Update the internal query with additional information. this.#internalQueries[index].selectedFields = selectedFields; + + if (this.#internalQueries[index].models.length === 0) { + this.#internalQueries[index].models = [model]; + } } this.models = modelsWithPresets; @@ -431,7 +440,7 @@ class Transaction { return this.#internalQueries.reduce( (finalResults: Array>, internalQuery) => { - const { query, selectedFields, affectedModels } = internalQuery; + const { query, selectedFields, models: affectedModels } = internalQuery; const { queryType, queryModel, queryInstructions } = splitQuery(query); // If the provided results are raw (rows being arrays of values, which is the most @@ -457,14 +466,10 @@ class Transaction { }); }) as Array>>); - if (queryModel === 'all' && affectedModels) { - const modelList = affectedModels.map((slug) => { - return getModelBySlug(this.models, slug); - }); - + if (queryModel === 'all') { const models: ExpandedResult['models'] = {}; - for (const model of modelList) { + for (const model of affectedModels) { const result = this.formatIndividualResult( queryType, queryInstructions, @@ -479,7 +484,7 @@ class Transaction { finalResults.push({ models }); } else { - const model = getModelBySlug(this.models, queryModel); + const model = affectedModels[0]; const result = this.formatIndividualResult( queryType, diff --git a/src/types/query.ts b/src/types/query.ts index 8874f88..90357a2 100644 --- a/src/types/query.ts +++ b/src/types/query.ts @@ -4,6 +4,7 @@ import type { ModelIndex, ModelPreset, ModelTrigger, + Model as PrivateModel, PublicModel, } from '@/src/types/model'; import { QUERY_SYMBOLS } from '@/src/utils/helpers'; @@ -227,11 +228,8 @@ export interface InternalQuery { query: Query; /** The RONIN model fields that were selected for the SQL statement. */ selectedFields: Array; - /** - * If the query addresses multiple models at once, this contains the list of models - * that are being addressed. - */ - affectedModels?: Array; + /** The RONIN models that are being affected by the query. */ + models: Array; } export interface InternalDependencyStatement extends Statement { diff --git a/src/utils/index.ts b/src/utils/index.ts index b70c044..6bbafe9 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,7 +6,11 @@ import { handleSelecting } from '@/src/instructions/selecting'; import { handleTo } from '@/src/instructions/to'; import { handleUsing } from '@/src/instructions/using'; import { handleWith } from '@/src/instructions/with'; -import { getModelBySlug, transformMetaQuery } from '@/src/model'; +import { + ROOT_MODEL_WITH_ATTRIBUTES, + getModelBySlug, + transformMetaQuery, +} from '@/src/model'; import type { InternalModelField, Model } from '@/src/types/model'; import type { CombinedInstructions, @@ -57,6 +61,7 @@ export const compileQueryInput = ( dependencies: Array; main: Statement; selectedFields: Array; + model: Model; } => { // A list of write statements that are required to be executed before the main read // statement. Their output is not relevant for the main statement, as they are merely @@ -83,6 +88,7 @@ export const compileQueryInput = ( dependencies: [], main: dependencyStatements[0], selectedFields: [], + model: ROOT_MODEL_WITH_ATTRIBUTES, }; // Split out the individual components of the query. @@ -334,5 +340,6 @@ export const compileQueryInput = ( dependencies: dependencyStatements, main: mainStatement, selectedFields, + model, }; };