Skip to content

Commit f2f6f88

Browse files
author
Elias Kassell
authored
Operation config as protos (#1766)
* Update operation to use config action fields * Fix tests, tidy filename * Tidy
1 parent 461faf8 commit f2f6f88

4 files changed

Lines changed: 87 additions & 97 deletions

File tree

core/actions/assertion.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ export class Assertion extends ActionBuilder<dataform.Assertion> {
7575
this.query(nativeRequire(config.filename).query);
7676
}
7777

78-
// TODO(ekrekr): load config proto column descriptors.
79-
8078
if (config.dependencyTargets) {
8179
this.dependencies(
8280
config.dependencyTargets.map(dependencyTarget =>

core/actions/operation.ts

Lines changed: 79 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,33 @@
11
import { verifyObjectMatchesProto, VerifyProtoErrorBehaviour } from "df/common/protos";
22
import { ActionBuilder } from "df/core/actions";
3-
import { LegacyColumnDescriptors } from "df/core/column_descriptors";
4-
import {
5-
Contextable,
6-
IActionConfig,
7-
IColumnsDescriptor,
8-
ICommonContext,
9-
IDependenciesConfig,
10-
IDocumentableConfig,
11-
INamedConfig,
12-
ITargetableConfig,
13-
Resolvable
14-
} from "df/core/common";
3+
import { ColumnDescriptors } from "df/core/column_descriptors";
4+
import { Contextable, ICommonContext, Resolvable } from "df/core/common";
155
import * as Path from "df/core/path";
166
import { Session } from "df/core/session";
177
import {
188
actionConfigToCompiledGraphTarget,
199
addDependenciesToActionDependencyTargets,
20-
checkExcessProperties,
2110
nativeRequire,
2211
resolvableAsTarget,
2312
resolveActionsConfigFilename,
2413
setNameAndTarget,
25-
strictKeysOf,
2614
toResolvable
2715
} from "df/core/utils";
2816
import { dataform } from "df/protos/ts";
2917

3018
/**
31-
* Configuration options for `operations` action types.
19+
* @hidden
20+
* This maintains backwards compatability with older versions.
21+
* TODO(ekrekr): consider breaking backwards compatability of these in v4.
3222
*/
33-
export interface IOperationConfig
34-
extends IActionConfig,
35-
IDependenciesConfig,
36-
IDocumentableConfig,
37-
INamedConfig,
38-
ITargetableConfig {
39-
/**
40-
* Declares that this `operations` action creates a dataset which should be referenceable using the `ref` function.
41-
*
42-
* If set to true, this action should create a dataset with its configured name, using the `self()` context function.
43-
*
44-
* For example:
45-
* ```sql
46-
* create or replace table ${self()} as select ...
47-
* ```
48-
*/
49-
hasOutput?: boolean;
23+
interface ILegacyOperationConfig extends dataform.ActionConfig.OperationConfig {
24+
dependencies: Resolvable[];
25+
database: string;
26+
schema: string;
27+
fileName: string;
28+
type: string;
5029
}
5130

52-
export const IIOperationConfigProperties = strictKeysOf<IOperationConfig>()([
53-
"columns",
54-
"database",
55-
"dependencies",
56-
"description",
57-
"disabled",
58-
"hasOutput",
59-
"hermetic",
60-
"name",
61-
"schema",
62-
"tags",
63-
"type",
64-
"dependOnDependencyAssertions"
65-
]);
66-
6731
/**
6832
* @hidden
6933
*/
@@ -80,18 +44,16 @@ export class Operation extends ActionBuilder<dataform.Operation> {
8044
// We delay contextification until the final compile step, so hold these here for now.
8145
private contextableQueries: Contextable<ICommonContext, string | string[]>;
8246

83-
constructor(
84-
session?: Session,
85-
config?: dataform.ActionConfig.OperationConfig,
86-
configPath?: string
87-
) {
47+
constructor(session?: Session, unverifiedConfig?: any, configPath?: string) {
8848
super(session);
8949
this.session = session;
9050

91-
if (!config) {
51+
if (!unverifiedConfig) {
9252
return;
9353
}
9454

55+
const config = this.verifyConfig(unverifiedConfig);
56+
9557
if (!config.name) {
9658
config.name = Path.basename(config.filename);
9759
}
@@ -104,37 +66,20 @@ export class Operation extends ActionBuilder<dataform.Operation> {
10466
);
10567
this.proto.canonicalTarget = this.applySessionToTarget(target, session.canonicalProjectConfig);
10668

107-
config.filename = resolveActionsConfigFilename(config.filename, configPath);
108-
this.proto.fileName = config.filename;
109-
110-
// TODO(ekrekr): load config proto column descriptors.
111-
this.config({
112-
dependencies: config.dependencyTargets.map(dependencyTarget =>
113-
actionConfigToCompiledGraphTarget(dataform.ActionConfig.Target.create(dependencyTarget))
114-
),
115-
tags: config.tags,
116-
disabled: config.disabled,
117-
hasOutput: config.hasOutput,
118-
description: config.description,
119-
dependOnDependencyAssertions: config.dependOnDependencyAssertions,
120-
hermetic: config.hermetic === true ? true : undefined
121-
});
122-
123-
this.queries(nativeRequire(config.filename).query);
124-
}
69+
if (configPath) {
70+
config.filename = resolveActionsConfigFilename(config.filename, configPath);
71+
this.queries(nativeRequire(config.filename).query);
72+
}
12573

126-
public config(config: IOperationConfig) {
127-
checkExcessProperties(
128-
(e: Error) => this.session.compileError(e),
129-
config,
130-
IIOperationConfigProperties,
131-
"operation config"
132-
);
13374
if (config.dependOnDependencyAssertions) {
13475
this.setDependOnDependencyAssertions(config.dependOnDependencyAssertions);
13576
}
136-
if (config.dependencies) {
137-
this.dependencies(config.dependencies);
77+
if (config.dependencyTargets) {
78+
this.dependencies(
79+
config.dependencyTargets.map(dependencyTarget =>
80+
actionConfigToCompiledGraphTarget(dataform.ActionConfig.Target.create(dependencyTarget))
81+
)
82+
);
13883
}
13984
if (config.hermetic !== undefined) {
14085
this.hermetic(config.hermetic);
@@ -151,14 +96,21 @@ export class Operation extends ActionBuilder<dataform.Operation> {
15196
if (config.description) {
15297
this.description(config.description);
15398
}
154-
if (config.columns) {
155-
this.columns(config.columns);
99+
if (config.columns?.length) {
100+
this.columns(
101+
config.columns.map(columnDescriptor =>
102+
dataform.ActionConfig.ColumnDescriptor.create(columnDescriptor)
103+
)
104+
);
105+
}
106+
if (config.project) {
107+
this.database(config.project);
156108
}
157-
if (config.database) {
158-
this.database(config.database);
109+
if (config.dataset) {
110+
this.schema(config.dataset);
159111
}
160-
if (config.schema) {
161-
this.schema(config.schema);
112+
if (config.filename) {
113+
this.proto.fileName = config.filename;
162114
}
163115
return this;
164116
}
@@ -210,13 +162,12 @@ export class Operation extends ActionBuilder<dataform.Operation> {
210162
return this;
211163
}
212164

213-
public columns(columns: IColumnsDescriptor) {
165+
public columns(columns: dataform.ActionConfig.ColumnDescriptor[]) {
214166
if (!this.proto.actionDescriptor) {
215167
this.proto.actionDescriptor = {};
216168
}
217-
this.proto.actionDescriptor.columns = LegacyColumnDescriptors.mapToColumnProtoArray(
218-
columns,
219-
(e: Error) => this.session.compileError(e)
169+
this.proto.actionDescriptor.columns = ColumnDescriptors.mapConfigProtoToCompilationProto(
170+
columns
220171
);
221172
return this;
222173
}
@@ -283,6 +234,44 @@ export class Operation extends ActionBuilder<dataform.Operation> {
283234
VerifyProtoErrorBehaviour.SUGGEST_REPORTING_TO_DATAFORM_TEAM
284235
);
285236
}
237+
238+
private verifyConfig(
239+
unverifiedConfig: ILegacyOperationConfig
240+
): dataform.ActionConfig.OperationConfig {
241+
// The "type" field only exists on legacy view configs. Here we convert them to the new format.
242+
if (unverifiedConfig.type) {
243+
delete unverifiedConfig.type;
244+
if (unverifiedConfig.dependencies) {
245+
unverifiedConfig.dependencyTargets = unverifiedConfig.dependencies.map(
246+
(dependency: string | object) =>
247+
typeof dependency === "string" ? { name: dependency } : dependency
248+
);
249+
delete unverifiedConfig.dependencies;
250+
}
251+
if (unverifiedConfig.database) {
252+
unverifiedConfig.project = unverifiedConfig.database;
253+
delete unverifiedConfig.database;
254+
}
255+
if (unverifiedConfig.schema) {
256+
unverifiedConfig.dataset = unverifiedConfig.schema;
257+
delete unverifiedConfig.schema;
258+
}
259+
if (unverifiedConfig.fileName) {
260+
unverifiedConfig.filename = unverifiedConfig.fileName;
261+
delete unverifiedConfig.fileName;
262+
}
263+
if (unverifiedConfig.columns) {
264+
unverifiedConfig.columns = ColumnDescriptors.mapLegacyObjectToConfigProto(
265+
unverifiedConfig.columns as any
266+
);
267+
}
268+
}
269+
return verifyObjectMatchesProto(
270+
dataform.ActionConfig.OperationConfig,
271+
unverifiedConfig,
272+
VerifyProtoErrorBehaviour.SHOW_DOCS_LINK
273+
);
274+
}
286275
}
287276

288277
/**

core/main_test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ actions:
187187
.sort()
188188
).deep.equals([
189189
`Action target datasets cannot include '.'`,
190+
`Action target datasets cannot include '.'`,
191+
`Action target names cannot include '.'`,
190192
`Action target names cannot include '.'`,
191193
`Action target names cannot include '.'`
192194
]);
@@ -890,7 +892,8 @@ actions:
890892
name: "action"
891893
},
892894
fileName: "definitions/action.sql",
893-
queries: ["SELECT 1"]
895+
queries: ["SELECT 1"],
896+
hermeticity: "NON_HERMETIC"
894897
}
895898
])
896899
);
@@ -1272,7 +1275,8 @@ actions:
12721275
name: "utf8characters:私🙂 and some spaces"
12731276
},
12741277
fileName: "definitions/utf8characters:私🙂 and some spaces.sql",
1275-
queries: ["SELECT 1"]
1278+
queries: ["SELECT 1"],
1279+
hermeticity: "NON_HERMETIC"
12761280
}
12771281
])
12781282
);

core/session.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,8 @@ export class Session {
186186
);
187187
break;
188188
case "operations":
189-
this.operate(sqlxConfig.name)
190-
.config(sqlxConfig)
191-
.queries(actionOptions.sqlContextable);
189+
sqlxConfig.filename = utils.getCallerFile(this.rootDir);
190+
this.actions.push(new Operation(this, sqlxConfig).queries(actionOptions.sqlContextable));
192191
break;
193192
case "declaration":
194193
const declaration = new Declaration(this, sqlxConfig);

0 commit comments

Comments
 (0)