Skip to content

Commit

Permalink
Merge pull request #778 from balena-io/select-model
Browse files Browse the repository at this point in the history
odata/abstract-sql-compiler: Add support for specifying the model name for config files
  • Loading branch information
Page- authored Jun 27, 2024
2 parents 81e2cd5 + 3118127 commit c1eee2b
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 10 deletions.
14 changes: 12 additions & 2 deletions src/bin/abstract-sql-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { program } from 'commander';

const runCompile = async (inputFile: string, outputFile?: string) => {
const { generateSqlModel } = await import('../sbvr-api/sbvr-utils.js');
const abstractSql = getAbstractSqlModelFromFile(inputFile);
const abstractSql = getAbstractSqlModelFromFile(
inputFile,
program.opts().model,
);
const sqlModel = generateSqlModel(abstractSql, program.opts().engine);

writeSqlModel(sqlModel, outputFile);
Expand All @@ -19,7 +22,10 @@ const generateTypes = async (inputFile: string, outputFile?: string) => {
const { abstractSqlToTypescriptTypes } = await import(
'@balena/abstract-sql-to-typescript/generate'
);
const abstractSql = getAbstractSqlModelFromFile(inputFile);
const abstractSql = getAbstractSqlModelFromFile(
inputFile,
program.opts().model,
);
const types = abstractSqlToTypescriptTypes(abstractSql);

writeAll(types, outputFile);
Expand All @@ -32,6 +38,10 @@ program
'The target database engine (postgres|websql|mysql), default: postgres',
/postgres|websql|mysql/,
'postgres',
)
.option(
'-m, --model <model-name>',
'The target model for config files with multiple models, default: first model',
);

program
Expand Down
30 changes: 25 additions & 5 deletions src/bin/odata-compiler.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { getAbstractSqlModelFromFile, version, writeAll } from './utils';
import type { SqlResult } from '@balena/abstract-sql-compiler';
import type {
AbstractSqlModel,
SqlResult,
} from '@balena/abstract-sql-compiler';

import { program } from 'commander';

const generateAbstractSqlQuery = async (modelFile: string, odata: string) => {
const generateAbstractSqlQuery = async (
abstractSqlModel: AbstractSqlModel,
odata: string,
) => {
const { memoizedParseOdata, translateUri } = await import(
'../sbvr-api/uri-parser.js'
);
Expand All @@ -19,7 +25,7 @@ const generateAbstractSqlQuery = async (modelFile: string, odata: string) => {
odataBinds: odataAST.binds,
values: {},
vocabulary,
abstractSqlModel: getAbstractSqlModelFromFile(modelFile),
abstractSqlModel,
custom: {},
translateVersions: [vocabulary],
});
Expand All @@ -37,7 +43,10 @@ const translateOData = async (
odata: string,
outputFile?: string,
) => {
const request = await generateAbstractSqlQuery(modelFile, odata);
const request = await generateAbstractSqlQuery(
getAbstractSqlModelFromFile(modelFile, program.opts().model),
odata,
);
const json = JSON.stringify(request.abstractSqlQuery, null, 2);
writeAll(json, outputFile);
};
Expand All @@ -58,7 +67,10 @@ const compileOData = async (
odata: string,
outputFile?: string,
) => {
const translatedRequest = await generateAbstractSqlQuery(modelFile, odata);
const translatedRequest = await generateAbstractSqlQuery(
getAbstractSqlModelFromFile(modelFile, program.opts().model),
odata,
);
const { compileRequest } = await import('../sbvr-api/abstract-sql.js');
const compiledRequest = compileRequest(translatedRequest);
let output;
Expand Down Expand Up @@ -88,11 +100,19 @@ program
program
.command('translate <model-file> <input-url> [output-file]')
.description('translate the input OData URL into abstract SQL')
.option(
'-m, --model <model-name>',
'The target model for config files with multiple models, default: first model',
)
.action(translateOData);

program
.command('compile <model-file> <input-url> [output-file]')
.description('compile the input OData URL into SQL')
.option(
'-m, --model <model-name>',
'The target model for config files with multiple models, default: first model',
)
.action(compileOData);

program
Expand Down
26 changes: 24 additions & 2 deletions src/bin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,31 @@ ${rule.sql}`,
writeAll(output, outputFile);
};

const getConfigModel = (
fileContents: Model | AbstractSqlModel | Config,
modelName?: string,
): Model | AbstractSqlModel => {
if ('models' in fileContents) {
if (fileContents.models.length === 0) {
throw new Error('No models found in config file');
}
if (modelName != null) {
const model = fileContents.models.find((m) => m.modelName === modelName);
if (model == null) {
throw new Error(
`Could not find model with name '${modelName}', found: ${fileContents.models.map((m) => m.modelName).join(', ')}`,
);
}
return model;
}
return fileContents.models[0];
}
return fileContents;
};

export const getAbstractSqlModelFromFile = (
modelFile: string,
modelName: string | undefined,
): AbstractSqlModel => {
let fileContents: string | Model | AbstractSqlModel | Config;
try {
Expand All @@ -67,8 +90,7 @@ export const getAbstractSqlModelFromFile = (
if ('tables' in fileContents) {
return fileContents;
}
const configModel =
'models' in fileContents ? fileContents.models[0] : fileContents;
const configModel = getConfigModel(fileContents, modelName);
if ('abstractSql' in configModel && configModel.abstractSql != null) {
return configModel.abstractSql as AbstractSqlModel;
} else if ('modelText' in configModel && configModel.modelText != null) {
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/04-translations/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { v1AbstractSqlModel, v1Translations } from './translations/v1';
import { v2AbstractSqlModel, v2Translations } from './translations/v2';
import { v3AbstractSqlModel, v3Translations } from './translations/v3';

export const abstractSql = getAbstractSqlModelFromFile(modelFile);
export const abstractSql = getAbstractSqlModelFromFile(modelFile, undefined);

abstractSql.tables['student'].fields.push({
fieldName: 'computed field',
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/04-translations/translations/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const toVersion = 'v2';

export const v1AbstractSqlModel = getAbstractSqlModelFromFile(
__dirname + '/university.sbvr',
undefined,
);

v1AbstractSqlModel.tables['student'].fields.push({
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/04-translations/translations/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {

export const v2AbstractSqlModel = getAbstractSqlModelFromFile(
__dirname + '/university.sbvr',
undefined,
);

export const toVersion = 'v3';
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/04-translations/translations/v3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler';

export const v3AbstractSqlModel = getAbstractSqlModelFromFile(
__dirname + '/university.sbvr',
undefined,
);

export const toVersion = 'university';
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/06-webresource/translations/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const toVersion = 'example';

export const v1AbstractSqlModel = getAbstractSqlModelFromFile(
__dirname + '/example.sbvr',
undefined,
);

v1AbstractSqlModel.relationships['version'] = { v1: {} };
Expand Down

0 comments on commit c1eee2b

Please sign in to comment.