@sqlanvil/cli 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/bundle.js +2500 -1207
  2. package/package.json +2 -1
  3. package/worker_bundle.js +1353 -173
package/bundle.js CHANGED
@@ -34,10 +34,11 @@ var pg = require('pg');
34
34
  var bigquery = require('@google-cloud/bigquery');
35
35
  var EventEmitter = require('events');
36
36
  var Long = require('long');
37
- var os = require('os');
37
+ var googleAuthLibrary = require('google-auth-library');
38
38
  var promisePoolExecutor = require('promise-pool-executor');
39
39
  var sizeof = require('object-sizeof');
40
40
  var QueryStream = require('pg-query-stream');
41
+ var os = require('os');
41
42
  var readlineSync = require('readline-sync');
42
43
  var untildify = require('untildify');
43
44
  var googleSqlSyntaxTs = require('google-sql-syntax-ts');
@@ -80,9 +81,9 @@ var mysql__namespace = /*#__PURE__*/_interopNamespace(mysql);
80
81
  var pg__namespace = /*#__PURE__*/_interopNamespace(pg);
81
82
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
82
83
  var Long__default = /*#__PURE__*/_interopDefaultLegacy(Long);
83
- var os__namespace = /*#__PURE__*/_interopNamespace(os);
84
84
  var sizeof__default = /*#__PURE__*/_interopDefaultLegacy(sizeof);
85
85
  var QueryStream__default = /*#__PURE__*/_interopDefaultLegacy(QueryStream);
86
+ var os__namespace = /*#__PURE__*/_interopNamespace(os);
86
87
  var readlineSync__namespace = /*#__PURE__*/_interopNamespace(readlineSync);
87
88
  var untildify__default = /*#__PURE__*/_interopDefaultLegacy(untildify);
88
89
  var jsBeautify__namespace = /*#__PURE__*/_interopNamespace(jsBeautify);
@@ -1282,6 +1283,7 @@ const sqlanvil = $root.sqlanvil = (() => {
1282
1283
  * @property {number|null} [port] ConnectionConfig port
1283
1284
  * @property {string|null} [database] ConnectionConfig database
1284
1285
  * @property {string|null} [defaultSchema] ConnectionConfig defaultSchema
1286
+ * @property {string|null} [mode] ConnectionConfig mode
1285
1287
  */
1286
1288
 
1287
1289
  /**
@@ -1371,6 +1373,14 @@ const sqlanvil = $root.sqlanvil = (() => {
1371
1373
  */
1372
1374
  ConnectionConfig.prototype.defaultSchema = "";
1373
1375
 
1376
+ /**
1377
+ * ConnectionConfig mode.
1378
+ * @member {string} mode
1379
+ * @memberof sqlanvil.ConnectionConfig
1380
+ * @instance
1381
+ */
1382
+ ConnectionConfig.prototype.mode = "";
1383
+
1374
1384
  /**
1375
1385
  * Creates a new ConnectionConfig instance using the specified properties.
1376
1386
  * @function create
@@ -1413,6 +1423,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1413
1423
  writer.uint32(/* id 8, wireType 2 =*/66).string(message.defaultSchema);
1414
1424
  if (message.billingProject != null && Object.hasOwnProperty.call(message, "billingProject"))
1415
1425
  writer.uint32(/* id 9, wireType 2 =*/74).string(message.billingProject);
1426
+ if (message.mode != null && Object.hasOwnProperty.call(message, "mode"))
1427
+ writer.uint32(/* id 10, wireType 2 =*/82).string(message.mode);
1416
1428
  return writer;
1417
1429
  };
1418
1430
 
@@ -1489,6 +1501,10 @@ const sqlanvil = $root.sqlanvil = (() => {
1489
1501
  message.defaultSchema = reader.string();
1490
1502
  break;
1491
1503
  }
1504
+ case 10: {
1505
+ message.mode = reader.string();
1506
+ break;
1507
+ }
1492
1508
  default:
1493
1509
  reader.skipType(tag & 7, long);
1494
1510
  break;
@@ -1555,6 +1571,9 @@ const sqlanvil = $root.sqlanvil = (() => {
1555
1571
  if (message.defaultSchema != null && message.hasOwnProperty("defaultSchema"))
1556
1572
  if (!$util.isString(message.defaultSchema))
1557
1573
  return "defaultSchema: string expected";
1574
+ if (message.mode != null && message.hasOwnProperty("mode"))
1575
+ if (!$util.isString(message.mode))
1576
+ return "mode: string expected";
1558
1577
  return null;
1559
1578
  };
1560
1579
 
@@ -1592,6 +1611,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1592
1611
  message.database = String(object.database);
1593
1612
  if (object.defaultSchema != null)
1594
1613
  message.defaultSchema = String(object.defaultSchema);
1614
+ if (object.mode != null)
1615
+ message.mode = String(object.mode);
1595
1616
  return message;
1596
1617
  };
1597
1618
 
@@ -1618,6 +1639,7 @@ const sqlanvil = $root.sqlanvil = (() => {
1618
1639
  object.database = "";
1619
1640
  object.defaultSchema = "";
1620
1641
  object.billingProject = "";
1642
+ object.mode = "";
1621
1643
  }
1622
1644
  if (message.platform != null && message.hasOwnProperty("platform"))
1623
1645
  object.platform = message.platform;
@@ -1637,6 +1659,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1637
1659
  object.defaultSchema = message.defaultSchema;
1638
1660
  if (message.billingProject != null && message.hasOwnProperty("billingProject"))
1639
1661
  object.billingProject = message.billingProject;
1662
+ if (message.mode != null && message.hasOwnProperty("mode"))
1663
+ object.mode = message.mode;
1640
1664
  return object;
1641
1665
  };
1642
1666
 
@@ -26389,6 +26413,668 @@ const sqlanvil = $root.sqlanvil = (() => {
26389
26413
  return Import;
26390
26414
  })();
26391
26415
 
26416
+ sqlanvil.Extract = (function() {
26417
+
26418
+ /**
26419
+ * Properties of an Extract.
26420
+ * @memberof sqlanvil
26421
+ * @interface IExtract
26422
+ * @property {sqlanvil.ITarget|null} [target] Extract target
26423
+ * @property {sqlanvil.ITarget|null} [canonicalTarget] Extract canonicalTarget
26424
+ * @property {Array.<sqlanvil.ITarget>|null} [dependencyTargets] Extract dependencyTargets
26425
+ * @property {sqlanvil.ActionHermeticity|null} [hermeticity] Extract hermeticity
26426
+ * @property {boolean|null} [disabled] Extract disabled
26427
+ * @property {Array.<string>|null} [tags] Extract tags
26428
+ * @property {sqlanvil.IActionDescriptor|null} [actionDescriptor] Extract actionDescriptor
26429
+ * @property {string|null} [connectionName] Extract connectionName
26430
+ * @property {string|null} [platform] Extract platform
26431
+ * @property {string|null} [project] Extract project
26432
+ * @property {string|null} [dataset] Extract dataset
26433
+ * @property {string|null} [sourceName] Extract sourceName
26434
+ * @property {string|null} [billingProject] Extract billingProject
26435
+ * @property {Object.<string,string>|null} [columnTypes] Extract columnTypes
26436
+ * @property {string|null} [fileName] Extract fileName
26437
+ */
26438
+
26439
+ /**
26440
+ * Constructs a new Extract.
26441
+ * @memberof sqlanvil
26442
+ * @classdesc Represents an Extract.
26443
+ * @implements IExtract
26444
+ * @constructor
26445
+ * @param {sqlanvil.IExtract=} [properties] Properties to set
26446
+ */
26447
+ function Extract(properties) {
26448
+ this.dependencyTargets = [];
26449
+ this.tags = [];
26450
+ this.columnTypes = {};
26451
+ if (properties)
26452
+ for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
26453
+ if (properties[keys[i]] != null && keys[i] !== "__proto__")
26454
+ this[keys[i]] = properties[keys[i]];
26455
+ }
26456
+
26457
+ /**
26458
+ * Extract target.
26459
+ * @member {sqlanvil.ITarget|null|undefined} target
26460
+ * @memberof sqlanvil.Extract
26461
+ * @instance
26462
+ */
26463
+ Extract.prototype.target = null;
26464
+
26465
+ /**
26466
+ * Extract canonicalTarget.
26467
+ * @member {sqlanvil.ITarget|null|undefined} canonicalTarget
26468
+ * @memberof sqlanvil.Extract
26469
+ * @instance
26470
+ */
26471
+ Extract.prototype.canonicalTarget = null;
26472
+
26473
+ /**
26474
+ * Extract dependencyTargets.
26475
+ * @member {Array.<sqlanvil.ITarget>} dependencyTargets
26476
+ * @memberof sqlanvil.Extract
26477
+ * @instance
26478
+ */
26479
+ Extract.prototype.dependencyTargets = $util.emptyArray;
26480
+
26481
+ /**
26482
+ * Extract hermeticity.
26483
+ * @member {sqlanvil.ActionHermeticity} hermeticity
26484
+ * @memberof sqlanvil.Extract
26485
+ * @instance
26486
+ */
26487
+ Extract.prototype.hermeticity = 0;
26488
+
26489
+ /**
26490
+ * Extract disabled.
26491
+ * @member {boolean} disabled
26492
+ * @memberof sqlanvil.Extract
26493
+ * @instance
26494
+ */
26495
+ Extract.prototype.disabled = false;
26496
+
26497
+ /**
26498
+ * Extract tags.
26499
+ * @member {Array.<string>} tags
26500
+ * @memberof sqlanvil.Extract
26501
+ * @instance
26502
+ */
26503
+ Extract.prototype.tags = $util.emptyArray;
26504
+
26505
+ /**
26506
+ * Extract actionDescriptor.
26507
+ * @member {sqlanvil.IActionDescriptor|null|undefined} actionDescriptor
26508
+ * @memberof sqlanvil.Extract
26509
+ * @instance
26510
+ */
26511
+ Extract.prototype.actionDescriptor = null;
26512
+
26513
+ /**
26514
+ * Extract connectionName.
26515
+ * @member {string} connectionName
26516
+ * @memberof sqlanvil.Extract
26517
+ * @instance
26518
+ */
26519
+ Extract.prototype.connectionName = "";
26520
+
26521
+ /**
26522
+ * Extract platform.
26523
+ * @member {string} platform
26524
+ * @memberof sqlanvil.Extract
26525
+ * @instance
26526
+ */
26527
+ Extract.prototype.platform = "";
26528
+
26529
+ /**
26530
+ * Extract project.
26531
+ * @member {string} project
26532
+ * @memberof sqlanvil.Extract
26533
+ * @instance
26534
+ */
26535
+ Extract.prototype.project = "";
26536
+
26537
+ /**
26538
+ * Extract dataset.
26539
+ * @member {string} dataset
26540
+ * @memberof sqlanvil.Extract
26541
+ * @instance
26542
+ */
26543
+ Extract.prototype.dataset = "";
26544
+
26545
+ /**
26546
+ * Extract sourceName.
26547
+ * @member {string} sourceName
26548
+ * @memberof sqlanvil.Extract
26549
+ * @instance
26550
+ */
26551
+ Extract.prototype.sourceName = "";
26552
+
26553
+ /**
26554
+ * Extract billingProject.
26555
+ * @member {string} billingProject
26556
+ * @memberof sqlanvil.Extract
26557
+ * @instance
26558
+ */
26559
+ Extract.prototype.billingProject = "";
26560
+
26561
+ /**
26562
+ * Extract columnTypes.
26563
+ * @member {Object.<string,string>} columnTypes
26564
+ * @memberof sqlanvil.Extract
26565
+ * @instance
26566
+ */
26567
+ Extract.prototype.columnTypes = $util.emptyObject;
26568
+
26569
+ /**
26570
+ * Extract fileName.
26571
+ * @member {string} fileName
26572
+ * @memberof sqlanvil.Extract
26573
+ * @instance
26574
+ */
26575
+ Extract.prototype.fileName = "";
26576
+
26577
+ /**
26578
+ * Creates a new Extract instance using the specified properties.
26579
+ * @function create
26580
+ * @memberof sqlanvil.Extract
26581
+ * @static
26582
+ * @param {sqlanvil.IExtract=} [properties] Properties to set
26583
+ * @returns {sqlanvil.Extract} Extract instance
26584
+ */
26585
+ Extract.create = function create(properties) {
26586
+ return new Extract(properties);
26587
+ };
26588
+
26589
+ /**
26590
+ * Encodes the specified Extract message. Does not implicitly {@link sqlanvil.Extract.verify|verify} messages.
26591
+ * @function encode
26592
+ * @memberof sqlanvil.Extract
26593
+ * @static
26594
+ * @param {sqlanvil.IExtract} message Extract message or plain object to encode
26595
+ * @param {$protobuf.Writer} [writer] Writer to encode to
26596
+ * @returns {$protobuf.Writer} Writer
26597
+ */
26598
+ Extract.encode = function encode(message, writer) {
26599
+ if (!writer)
26600
+ writer = $Writer.create();
26601
+ if (message.target != null && Object.hasOwnProperty.call(message, "target"))
26602
+ $root.sqlanvil.Target.encode(message.target, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
26603
+ if (message.canonicalTarget != null && Object.hasOwnProperty.call(message, "canonicalTarget"))
26604
+ $root.sqlanvil.Target.encode(message.canonicalTarget, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
26605
+ if (message.dependencyTargets != null && message.dependencyTargets.length)
26606
+ for (let i = 0; i < message.dependencyTargets.length; ++i)
26607
+ $root.sqlanvil.Target.encode(message.dependencyTargets[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
26608
+ if (message.hermeticity != null && Object.hasOwnProperty.call(message, "hermeticity"))
26609
+ writer.uint32(/* id 4, wireType 0 =*/32).int32(message.hermeticity);
26610
+ if (message.disabled != null && Object.hasOwnProperty.call(message, "disabled"))
26611
+ writer.uint32(/* id 5, wireType 0 =*/40).bool(message.disabled);
26612
+ if (message.tags != null && message.tags.length)
26613
+ for (let i = 0; i < message.tags.length; ++i)
26614
+ writer.uint32(/* id 6, wireType 2 =*/50).string(message.tags[i]);
26615
+ if (message.actionDescriptor != null && Object.hasOwnProperty.call(message, "actionDescriptor"))
26616
+ $root.sqlanvil.ActionDescriptor.encode(message.actionDescriptor, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
26617
+ if (message.connectionName != null && Object.hasOwnProperty.call(message, "connectionName"))
26618
+ writer.uint32(/* id 8, wireType 2 =*/66).string(message.connectionName);
26619
+ if (message.platform != null && Object.hasOwnProperty.call(message, "platform"))
26620
+ writer.uint32(/* id 9, wireType 2 =*/74).string(message.platform);
26621
+ if (message.project != null && Object.hasOwnProperty.call(message, "project"))
26622
+ writer.uint32(/* id 10, wireType 2 =*/82).string(message.project);
26623
+ if (message.dataset != null && Object.hasOwnProperty.call(message, "dataset"))
26624
+ writer.uint32(/* id 11, wireType 2 =*/90).string(message.dataset);
26625
+ if (message.sourceName != null && Object.hasOwnProperty.call(message, "sourceName"))
26626
+ writer.uint32(/* id 12, wireType 2 =*/98).string(message.sourceName);
26627
+ if (message.billingProject != null && Object.hasOwnProperty.call(message, "billingProject"))
26628
+ writer.uint32(/* id 13, wireType 2 =*/106).string(message.billingProject);
26629
+ if (message.columnTypes != null && Object.hasOwnProperty.call(message, "columnTypes"))
26630
+ for (let keys = Object.keys(message.columnTypes), i = 0; i < keys.length; ++i)
26631
+ writer.uint32(/* id 14, wireType 2 =*/114).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.columnTypes[keys[i]]).ldelim();
26632
+ if (message.fileName != null && Object.hasOwnProperty.call(message, "fileName"))
26633
+ writer.uint32(/* id 15, wireType 2 =*/122).string(message.fileName);
26634
+ return writer;
26635
+ };
26636
+
26637
+ /**
26638
+ * Encodes the specified Extract message, length delimited. Does not implicitly {@link sqlanvil.Extract.verify|verify} messages.
26639
+ * @function encodeDelimited
26640
+ * @memberof sqlanvil.Extract
26641
+ * @static
26642
+ * @param {sqlanvil.IExtract} message Extract message or plain object to encode
26643
+ * @param {$protobuf.Writer} [writer] Writer to encode to
26644
+ * @returns {$protobuf.Writer} Writer
26645
+ */
26646
+ Extract.encodeDelimited = function encodeDelimited(message, writer) {
26647
+ return this.encode(message, writer).ldelim();
26648
+ };
26649
+
26650
+ /**
26651
+ * Decodes an Extract message from the specified reader or buffer.
26652
+ * @function decode
26653
+ * @memberof sqlanvil.Extract
26654
+ * @static
26655
+ * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
26656
+ * @param {number} [length] Message length if known beforehand
26657
+ * @returns {sqlanvil.Extract} Extract
26658
+ * @throws {Error} If the payload is not a reader or valid buffer
26659
+ * @throws {$protobuf.util.ProtocolError} If required fields are missing
26660
+ */
26661
+ Extract.decode = function decode(reader, length, error, long) {
26662
+ if (!(reader instanceof $Reader))
26663
+ reader = $Reader.create(reader);
26664
+ if (long === undefined)
26665
+ long = 0;
26666
+ if (long > $Reader.recursionLimit)
26667
+ throw Error("maximum nesting depth exceeded");
26668
+ let end = length === undefined ? reader.len : reader.pos + length, message = new $root.sqlanvil.Extract(), key, value;
26669
+ while (reader.pos < end) {
26670
+ let tag = reader.uint32();
26671
+ if (tag === error)
26672
+ break;
26673
+ switch (tag >>> 3) {
26674
+ case 1: {
26675
+ message.target = $root.sqlanvil.Target.decode(reader, reader.uint32(), undefined, long + 1);
26676
+ break;
26677
+ }
26678
+ case 2: {
26679
+ message.canonicalTarget = $root.sqlanvil.Target.decode(reader, reader.uint32(), undefined, long + 1);
26680
+ break;
26681
+ }
26682
+ case 3: {
26683
+ if (!(message.dependencyTargets && message.dependencyTargets.length))
26684
+ message.dependencyTargets = [];
26685
+ message.dependencyTargets.push($root.sqlanvil.Target.decode(reader, reader.uint32(), undefined, long + 1));
26686
+ break;
26687
+ }
26688
+ case 4: {
26689
+ message.hermeticity = reader.int32();
26690
+ break;
26691
+ }
26692
+ case 5: {
26693
+ message.disabled = reader.bool();
26694
+ break;
26695
+ }
26696
+ case 6: {
26697
+ if (!(message.tags && message.tags.length))
26698
+ message.tags = [];
26699
+ message.tags.push(reader.string());
26700
+ break;
26701
+ }
26702
+ case 7: {
26703
+ message.actionDescriptor = $root.sqlanvil.ActionDescriptor.decode(reader, reader.uint32(), undefined, long + 1);
26704
+ break;
26705
+ }
26706
+ case 8: {
26707
+ message.connectionName = reader.string();
26708
+ break;
26709
+ }
26710
+ case 9: {
26711
+ message.platform = reader.string();
26712
+ break;
26713
+ }
26714
+ case 10: {
26715
+ message.project = reader.string();
26716
+ break;
26717
+ }
26718
+ case 11: {
26719
+ message.dataset = reader.string();
26720
+ break;
26721
+ }
26722
+ case 12: {
26723
+ message.sourceName = reader.string();
26724
+ break;
26725
+ }
26726
+ case 13: {
26727
+ message.billingProject = reader.string();
26728
+ break;
26729
+ }
26730
+ case 14: {
26731
+ if (message.columnTypes === $util.emptyObject)
26732
+ message.columnTypes = {};
26733
+ let end2 = reader.uint32() + reader.pos;
26734
+ key = "";
26735
+ value = "";
26736
+ while (reader.pos < end2) {
26737
+ let tag2 = reader.uint32();
26738
+ switch (tag2 >>> 3) {
26739
+ case 1:
26740
+ key = reader.string();
26741
+ break;
26742
+ case 2:
26743
+ value = reader.string();
26744
+ break;
26745
+ default:
26746
+ reader.skipType(tag2 & 7, long);
26747
+ break;
26748
+ }
26749
+ }
26750
+ if (key === "__proto__")
26751
+ $util.makeProp(message.columnTypes, key);
26752
+ message.columnTypes[key] = value;
26753
+ break;
26754
+ }
26755
+ case 15: {
26756
+ message.fileName = reader.string();
26757
+ break;
26758
+ }
26759
+ default:
26760
+ reader.skipType(tag & 7, long);
26761
+ break;
26762
+ }
26763
+ }
26764
+ return message;
26765
+ };
26766
+
26767
+ /**
26768
+ * Decodes an Extract message from the specified reader or buffer, length delimited.
26769
+ * @function decodeDelimited
26770
+ * @memberof sqlanvil.Extract
26771
+ * @static
26772
+ * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
26773
+ * @returns {sqlanvil.Extract} Extract
26774
+ * @throws {Error} If the payload is not a reader or valid buffer
26775
+ * @throws {$protobuf.util.ProtocolError} If required fields are missing
26776
+ */
26777
+ Extract.decodeDelimited = function decodeDelimited(reader) {
26778
+ if (!(reader instanceof $Reader))
26779
+ reader = new $Reader(reader);
26780
+ return this.decode(reader, reader.uint32());
26781
+ };
26782
+
26783
+ /**
26784
+ * Verifies an Extract message.
26785
+ * @function verify
26786
+ * @memberof sqlanvil.Extract
26787
+ * @static
26788
+ * @param {Object.<string,*>} message Plain object to verify
26789
+ * @returns {string|null} `null` if valid, otherwise the reason why it is not
26790
+ */
26791
+ Extract.verify = function verify(message, long) {
26792
+ if (typeof message !== "object" || message === null)
26793
+ return "object expected";
26794
+ if (long === undefined)
26795
+ long = 0;
26796
+ if (long > $util.recursionLimit)
26797
+ return "maximum nesting depth exceeded";
26798
+ if (message.target != null && message.hasOwnProperty("target")) {
26799
+ let error = $root.sqlanvil.Target.verify(message.target, long + 1);
26800
+ if (error)
26801
+ return "target." + error;
26802
+ }
26803
+ if (message.canonicalTarget != null && message.hasOwnProperty("canonicalTarget")) {
26804
+ let error = $root.sqlanvil.Target.verify(message.canonicalTarget, long + 1);
26805
+ if (error)
26806
+ return "canonicalTarget." + error;
26807
+ }
26808
+ if (message.dependencyTargets != null && message.hasOwnProperty("dependencyTargets")) {
26809
+ if (!Array.isArray(message.dependencyTargets))
26810
+ return "dependencyTargets: array expected";
26811
+ for (let i = 0; i < message.dependencyTargets.length; ++i) {
26812
+ let error = $root.sqlanvil.Target.verify(message.dependencyTargets[i], long + 1);
26813
+ if (error)
26814
+ return "dependencyTargets." + error;
26815
+ }
26816
+ }
26817
+ if (message.hermeticity != null && message.hasOwnProperty("hermeticity"))
26818
+ switch (message.hermeticity) {
26819
+ default:
26820
+ return "hermeticity: enum value expected";
26821
+ case 0:
26822
+ case 1:
26823
+ case 2:
26824
+ break;
26825
+ }
26826
+ if (message.disabled != null && message.hasOwnProperty("disabled"))
26827
+ if (typeof message.disabled !== "boolean")
26828
+ return "disabled: boolean expected";
26829
+ if (message.tags != null && message.hasOwnProperty("tags")) {
26830
+ if (!Array.isArray(message.tags))
26831
+ return "tags: array expected";
26832
+ for (let i = 0; i < message.tags.length; ++i)
26833
+ if (!$util.isString(message.tags[i]))
26834
+ return "tags: string[] expected";
26835
+ }
26836
+ if (message.actionDescriptor != null && message.hasOwnProperty("actionDescriptor")) {
26837
+ let error = $root.sqlanvil.ActionDescriptor.verify(message.actionDescriptor, long + 1);
26838
+ if (error)
26839
+ return "actionDescriptor." + error;
26840
+ }
26841
+ if (message.connectionName != null && message.hasOwnProperty("connectionName"))
26842
+ if (!$util.isString(message.connectionName))
26843
+ return "connectionName: string expected";
26844
+ if (message.platform != null && message.hasOwnProperty("platform"))
26845
+ if (!$util.isString(message.platform))
26846
+ return "platform: string expected";
26847
+ if (message.project != null && message.hasOwnProperty("project"))
26848
+ if (!$util.isString(message.project))
26849
+ return "project: string expected";
26850
+ if (message.dataset != null && message.hasOwnProperty("dataset"))
26851
+ if (!$util.isString(message.dataset))
26852
+ return "dataset: string expected";
26853
+ if (message.sourceName != null && message.hasOwnProperty("sourceName"))
26854
+ if (!$util.isString(message.sourceName))
26855
+ return "sourceName: string expected";
26856
+ if (message.billingProject != null && message.hasOwnProperty("billingProject"))
26857
+ if (!$util.isString(message.billingProject))
26858
+ return "billingProject: string expected";
26859
+ if (message.columnTypes != null && message.hasOwnProperty("columnTypes")) {
26860
+ if (!$util.isObject(message.columnTypes))
26861
+ return "columnTypes: object expected";
26862
+ let key = Object.keys(message.columnTypes);
26863
+ for (let i = 0; i < key.length; ++i)
26864
+ if (!$util.isString(message.columnTypes[key[i]]))
26865
+ return "columnTypes: string{k:string} expected";
26866
+ }
26867
+ if (message.fileName != null && message.hasOwnProperty("fileName"))
26868
+ if (!$util.isString(message.fileName))
26869
+ return "fileName: string expected";
26870
+ return null;
26871
+ };
26872
+
26873
+ /**
26874
+ * Creates an Extract message from a plain object. Also converts values to their respective internal types.
26875
+ * @function fromObject
26876
+ * @memberof sqlanvil.Extract
26877
+ * @static
26878
+ * @param {Object.<string,*>} object Plain object
26879
+ * @returns {sqlanvil.Extract} Extract
26880
+ */
26881
+ Extract.fromObject = function fromObject(object, long) {
26882
+ if (object instanceof $root.sqlanvil.Extract)
26883
+ return object;
26884
+ if (long === undefined)
26885
+ long = 0;
26886
+ if (long > $util.recursionLimit)
26887
+ throw Error("maximum nesting depth exceeded");
26888
+ let message = new $root.sqlanvil.Extract();
26889
+ if (object.target != null) {
26890
+ if (typeof object.target !== "object")
26891
+ throw TypeError(".sqlanvil.Extract.target: object expected");
26892
+ message.target = $root.sqlanvil.Target.fromObject(object.target, long + 1);
26893
+ }
26894
+ if (object.canonicalTarget != null) {
26895
+ if (typeof object.canonicalTarget !== "object")
26896
+ throw TypeError(".sqlanvil.Extract.canonicalTarget: object expected");
26897
+ message.canonicalTarget = $root.sqlanvil.Target.fromObject(object.canonicalTarget, long + 1);
26898
+ }
26899
+ if (object.dependencyTargets) {
26900
+ if (!Array.isArray(object.dependencyTargets))
26901
+ throw TypeError(".sqlanvil.Extract.dependencyTargets: array expected");
26902
+ message.dependencyTargets = [];
26903
+ for (let i = 0; i < object.dependencyTargets.length; ++i) {
26904
+ if (typeof object.dependencyTargets[i] !== "object")
26905
+ throw TypeError(".sqlanvil.Extract.dependencyTargets: object expected");
26906
+ message.dependencyTargets[i] = $root.sqlanvil.Target.fromObject(object.dependencyTargets[i], long + 1);
26907
+ }
26908
+ }
26909
+ switch (object.hermeticity) {
26910
+ default:
26911
+ if (typeof object.hermeticity === "number") {
26912
+ message.hermeticity = object.hermeticity;
26913
+ break;
26914
+ }
26915
+ break;
26916
+ case "UNKNOWN":
26917
+ case 0:
26918
+ message.hermeticity = 0;
26919
+ break;
26920
+ case "HERMETIC":
26921
+ case 1:
26922
+ message.hermeticity = 1;
26923
+ break;
26924
+ case "NON_HERMETIC":
26925
+ case 2:
26926
+ message.hermeticity = 2;
26927
+ break;
26928
+ }
26929
+ if (object.disabled != null)
26930
+ message.disabled = Boolean(object.disabled);
26931
+ if (object.tags) {
26932
+ if (!Array.isArray(object.tags))
26933
+ throw TypeError(".sqlanvil.Extract.tags: array expected");
26934
+ message.tags = [];
26935
+ for (let i = 0; i < object.tags.length; ++i)
26936
+ message.tags[i] = String(object.tags[i]);
26937
+ }
26938
+ if (object.actionDescriptor != null) {
26939
+ if (typeof object.actionDescriptor !== "object")
26940
+ throw TypeError(".sqlanvil.Extract.actionDescriptor: object expected");
26941
+ message.actionDescriptor = $root.sqlanvil.ActionDescriptor.fromObject(object.actionDescriptor, long + 1);
26942
+ }
26943
+ if (object.connectionName != null)
26944
+ message.connectionName = String(object.connectionName);
26945
+ if (object.platform != null)
26946
+ message.platform = String(object.platform);
26947
+ if (object.project != null)
26948
+ message.project = String(object.project);
26949
+ if (object.dataset != null)
26950
+ message.dataset = String(object.dataset);
26951
+ if (object.sourceName != null)
26952
+ message.sourceName = String(object.sourceName);
26953
+ if (object.billingProject != null)
26954
+ message.billingProject = String(object.billingProject);
26955
+ if (object.columnTypes) {
26956
+ if (typeof object.columnTypes !== "object")
26957
+ throw TypeError(".sqlanvil.Extract.columnTypes: object expected");
26958
+ message.columnTypes = {};
26959
+ for (let keys = Object.keys(object.columnTypes), i = 0; i < keys.length; ++i) {
26960
+ if (keys[i] === "__proto__")
26961
+ $util.makeProp(message.columnTypes, keys[i]);
26962
+ message.columnTypes[keys[i]] = String(object.columnTypes[keys[i]]);
26963
+ }
26964
+ }
26965
+ if (object.fileName != null)
26966
+ message.fileName = String(object.fileName);
26967
+ return message;
26968
+ };
26969
+
26970
+ /**
26971
+ * Creates a plain object from an Extract message. Also converts values to other types if specified.
26972
+ * @function toObject
26973
+ * @memberof sqlanvil.Extract
26974
+ * @static
26975
+ * @param {sqlanvil.Extract} message Extract
26976
+ * @param {$protobuf.IConversionOptions} [options] Conversion options
26977
+ * @returns {Object.<string,*>} Plain object
26978
+ */
26979
+ Extract.toObject = function toObject(message, options) {
26980
+ if (!options)
26981
+ options = {};
26982
+ let object = {};
26983
+ if (options.arrays || options.defaults) {
26984
+ object.dependencyTargets = [];
26985
+ object.tags = [];
26986
+ }
26987
+ if (options.objects || options.defaults)
26988
+ object.columnTypes = {};
26989
+ if (options.defaults) {
26990
+ object.target = null;
26991
+ object.canonicalTarget = null;
26992
+ object.hermeticity = options.enums === String ? "UNKNOWN" : 0;
26993
+ object.disabled = false;
26994
+ object.actionDescriptor = null;
26995
+ object.connectionName = "";
26996
+ object.platform = "";
26997
+ object.project = "";
26998
+ object.dataset = "";
26999
+ object.sourceName = "";
27000
+ object.billingProject = "";
27001
+ object.fileName = "";
27002
+ }
27003
+ if (message.target != null && message.hasOwnProperty("target"))
27004
+ object.target = $root.sqlanvil.Target.toObject(message.target, options);
27005
+ if (message.canonicalTarget != null && message.hasOwnProperty("canonicalTarget"))
27006
+ object.canonicalTarget = $root.sqlanvil.Target.toObject(message.canonicalTarget, options);
27007
+ if (message.dependencyTargets && message.dependencyTargets.length) {
27008
+ object.dependencyTargets = [];
27009
+ for (let j = 0; j < message.dependencyTargets.length; ++j)
27010
+ object.dependencyTargets[j] = $root.sqlanvil.Target.toObject(message.dependencyTargets[j], options);
27011
+ }
27012
+ if (message.hermeticity != null && message.hasOwnProperty("hermeticity"))
27013
+ object.hermeticity = options.enums === String ? $root.sqlanvil.ActionHermeticity[message.hermeticity] === undefined ? message.hermeticity : $root.sqlanvil.ActionHermeticity[message.hermeticity] : message.hermeticity;
27014
+ if (message.disabled != null && message.hasOwnProperty("disabled"))
27015
+ object.disabled = message.disabled;
27016
+ if (message.tags && message.tags.length) {
27017
+ object.tags = [];
27018
+ for (let j = 0; j < message.tags.length; ++j)
27019
+ object.tags[j] = message.tags[j];
27020
+ }
27021
+ if (message.actionDescriptor != null && message.hasOwnProperty("actionDescriptor"))
27022
+ object.actionDescriptor = $root.sqlanvil.ActionDescriptor.toObject(message.actionDescriptor, options);
27023
+ if (message.connectionName != null && message.hasOwnProperty("connectionName"))
27024
+ object.connectionName = message.connectionName;
27025
+ if (message.platform != null && message.hasOwnProperty("platform"))
27026
+ object.platform = message.platform;
27027
+ if (message.project != null && message.hasOwnProperty("project"))
27028
+ object.project = message.project;
27029
+ if (message.dataset != null && message.hasOwnProperty("dataset"))
27030
+ object.dataset = message.dataset;
27031
+ if (message.sourceName != null && message.hasOwnProperty("sourceName"))
27032
+ object.sourceName = message.sourceName;
27033
+ if (message.billingProject != null && message.hasOwnProperty("billingProject"))
27034
+ object.billingProject = message.billingProject;
27035
+ let keys2;
27036
+ if (message.columnTypes && (keys2 = Object.keys(message.columnTypes)).length) {
27037
+ object.columnTypes = {};
27038
+ for (let j = 0; j < keys2.length; ++j) {
27039
+ if (keys2[j] === "__proto__")
27040
+ $util.makeProp(object.columnTypes, keys2[j]);
27041
+ object.columnTypes[keys2[j]] = message.columnTypes[keys2[j]];
27042
+ }
27043
+ }
27044
+ if (message.fileName != null && message.hasOwnProperty("fileName"))
27045
+ object.fileName = message.fileName;
27046
+ return object;
27047
+ };
27048
+
27049
+ /**
27050
+ * Converts this Extract to JSON.
27051
+ * @function toJSON
27052
+ * @memberof sqlanvil.Extract
27053
+ * @instance
27054
+ * @returns {Object.<string,*>} JSON object
27055
+ */
27056
+ Extract.prototype.toJSON = function toJSON() {
27057
+ return this.constructor.toObject(this, $protobuf__namespace.util.toJSONOptions);
27058
+ };
27059
+
27060
+ /**
27061
+ * Gets the default type url for Extract
27062
+ * @function getTypeUrl
27063
+ * @memberof sqlanvil.Extract
27064
+ * @static
27065
+ * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
27066
+ * @returns {string} The default type url
27067
+ */
27068
+ Extract.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
27069
+ if (typeUrlPrefix === undefined) {
27070
+ typeUrlPrefix = "type.googleapis.com";
27071
+ }
27072
+ return typeUrlPrefix + "/sqlanvil.Extract";
27073
+ };
27074
+
27075
+ return Extract;
27076
+ })();
27077
+
26392
27078
  sqlanvil.Assertion = (function() {
26393
27079
 
26394
27080
  /**
@@ -30365,6 +31051,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30365
31051
  * @property {Array.<sqlanvil.IDataPreparation>|null} [dataPreparations] CompiledGraph dataPreparations
30366
31052
  * @property {Array.<sqlanvil.IExport>|null} [exports] CompiledGraph exports
30367
31053
  * @property {Array.<sqlanvil.IImport>|null} [imports] CompiledGraph imports
31054
+ * @property {Array.<sqlanvil.IExtract>|null} [extracts] CompiledGraph extracts
30368
31055
  * @property {sqlanvil.IGraphErrors|null} [graphErrors] CompiledGraph graphErrors
30369
31056
  * @property {string|null} [sqlanvilCoreVersion] CompiledGraph sqlanvilCoreVersion
30370
31057
  * @property {Array.<sqlanvil.ITarget>|null} [targets] CompiledGraph targets
@@ -30389,6 +31076,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30389
31076
  this.dataPreparations = [];
30390
31077
  this.exports = [];
30391
31078
  this.imports = [];
31079
+ this.extracts = [];
30392
31080
  this.targets = [];
30393
31081
  if (properties)
30394
31082
  for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
@@ -30476,6 +31164,14 @@ const sqlanvil = $root.sqlanvil = (() => {
30476
31164
  */
30477
31165
  CompiledGraph.prototype.imports = $util.emptyArray;
30478
31166
 
31167
+ /**
31168
+ * CompiledGraph extracts.
31169
+ * @member {Array.<sqlanvil.IExtract>} extracts
31170
+ * @memberof sqlanvil.CompiledGraph
31171
+ * @instance
31172
+ */
31173
+ CompiledGraph.prototype.extracts = $util.emptyArray;
31174
+
30479
31175
  /**
30480
31176
  * CompiledGraph graphErrors.
30481
31177
  * @member {sqlanvil.IGraphErrors|null|undefined} graphErrors
@@ -30570,6 +31266,9 @@ const sqlanvil = $root.sqlanvil = (() => {
30570
31266
  if (message.imports != null && message.imports.length)
30571
31267
  for (let i = 0; i < message.imports.length; ++i)
30572
31268
  $root.sqlanvil.Import.encode(message.imports[i], writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim();
31269
+ if (message.extracts != null && message.extracts.length)
31270
+ for (let i = 0; i < message.extracts.length; ++i)
31271
+ $root.sqlanvil.Extract.encode(message.extracts[i], writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
30573
31272
  return writer;
30574
31273
  };
30575
31274
 
@@ -30668,6 +31367,12 @@ const sqlanvil = $root.sqlanvil = (() => {
30668
31367
  message.imports.push($root.sqlanvil.Import.decode(reader, reader.uint32(), undefined, long + 1));
30669
31368
  break;
30670
31369
  }
31370
+ case 17: {
31371
+ if (!(message.extracts && message.extracts.length))
31372
+ message.extracts = [];
31373
+ message.extracts.push($root.sqlanvil.Extract.decode(reader, reader.uint32(), undefined, long + 1));
31374
+ break;
31375
+ }
30671
31376
  case 7: {
30672
31377
  message.graphErrors = $root.sqlanvil.GraphErrors.decode(reader, reader.uint32(), undefined, long + 1);
30673
31378
  break;
@@ -30811,6 +31516,15 @@ const sqlanvil = $root.sqlanvil = (() => {
30811
31516
  return "imports." + error;
30812
31517
  }
30813
31518
  }
31519
+ if (message.extracts != null && message.hasOwnProperty("extracts")) {
31520
+ if (!Array.isArray(message.extracts))
31521
+ return "extracts: array expected";
31522
+ for (let i = 0; i < message.extracts.length; ++i) {
31523
+ let error = $root.sqlanvil.Extract.verify(message.extracts[i], long + 1);
31524
+ if (error)
31525
+ return "extracts." + error;
31526
+ }
31527
+ }
30814
31528
  if (message.graphErrors != null && message.hasOwnProperty("graphErrors")) {
30815
31529
  let error = $root.sqlanvil.GraphErrors.verify(message.graphErrors, long + 1);
30816
31530
  if (error)
@@ -30947,6 +31661,16 @@ const sqlanvil = $root.sqlanvil = (() => {
30947
31661
  message.imports[i] = $root.sqlanvil.Import.fromObject(object.imports[i], long + 1);
30948
31662
  }
30949
31663
  }
31664
+ if (object.extracts) {
31665
+ if (!Array.isArray(object.extracts))
31666
+ throw TypeError(".sqlanvil.CompiledGraph.extracts: array expected");
31667
+ message.extracts = [];
31668
+ for (let i = 0; i < object.extracts.length; ++i) {
31669
+ if (typeof object.extracts[i] !== "object")
31670
+ throw TypeError(".sqlanvil.CompiledGraph.extracts: object expected");
31671
+ message.extracts[i] = $root.sqlanvil.Extract.fromObject(object.extracts[i], long + 1);
31672
+ }
31673
+ }
30950
31674
  if (object.graphErrors != null) {
30951
31675
  if (typeof object.graphErrors !== "object")
30952
31676
  throw TypeError(".sqlanvil.CompiledGraph.graphErrors: object expected");
@@ -30996,6 +31720,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30996
31720
  object.dataPreparations = [];
30997
31721
  object.exports = [];
30998
31722
  object.imports = [];
31723
+ object.extracts = [];
30999
31724
  }
31000
31725
  if (options.defaults) {
31001
31726
  object.projectConfig = null;
@@ -31061,6 +31786,11 @@ const sqlanvil = $root.sqlanvil = (() => {
31061
31786
  for (let j = 0; j < message.imports.length; ++j)
31062
31787
  object.imports[j] = $root.sqlanvil.Import.toObject(message.imports[j], options);
31063
31788
  }
31789
+ if (message.extracts && message.extracts.length) {
31790
+ object.extracts = [];
31791
+ for (let j = 0; j < message.extracts.length; ++j)
31792
+ object.extracts[j] = $root.sqlanvil.Extract.toObject(message.extracts[j], options);
31793
+ }
31064
31794
  return object;
31065
31795
  };
31066
31796
 
@@ -36183,6 +36913,406 @@ const sqlanvil = $root.sqlanvil = (() => {
36183
36913
  return ImportSpec;
36184
36914
  })();
36185
36915
 
36916
+ sqlanvil.ExtractSpec = (function() {
36917
+
36918
+ /**
36919
+ * Properties of an ExtractSpec.
36920
+ * @memberof sqlanvil
36921
+ * @interface IExtractSpec
36922
+ * @property {string|null} [connectionName] ExtractSpec connectionName
36923
+ * @property {string|null} [platform] ExtractSpec platform
36924
+ * @property {string|null} [project] ExtractSpec project
36925
+ * @property {string|null} [dataset] ExtractSpec dataset
36926
+ * @property {string|null} [sourceName] ExtractSpec sourceName
36927
+ * @property {string|null} [billingProject] ExtractSpec billingProject
36928
+ * @property {Object.<string,string>|null} [columnTypes] ExtractSpec columnTypes
36929
+ */
36930
+
36931
+ /**
36932
+ * Constructs a new ExtractSpec.
36933
+ * @memberof sqlanvil
36934
+ * @classdesc Represents an ExtractSpec.
36935
+ * @implements IExtractSpec
36936
+ * @constructor
36937
+ * @param {sqlanvil.IExtractSpec=} [properties] Properties to set
36938
+ */
36939
+ function ExtractSpec(properties) {
36940
+ this.columnTypes = {};
36941
+ if (properties)
36942
+ for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
36943
+ if (properties[keys[i]] != null && keys[i] !== "__proto__")
36944
+ this[keys[i]] = properties[keys[i]];
36945
+ }
36946
+
36947
+ /**
36948
+ * ExtractSpec connectionName.
36949
+ * @member {string} connectionName
36950
+ * @memberof sqlanvil.ExtractSpec
36951
+ * @instance
36952
+ */
36953
+ ExtractSpec.prototype.connectionName = "";
36954
+
36955
+ /**
36956
+ * ExtractSpec platform.
36957
+ * @member {string} platform
36958
+ * @memberof sqlanvil.ExtractSpec
36959
+ * @instance
36960
+ */
36961
+ ExtractSpec.prototype.platform = "";
36962
+
36963
+ /**
36964
+ * ExtractSpec project.
36965
+ * @member {string} project
36966
+ * @memberof sqlanvil.ExtractSpec
36967
+ * @instance
36968
+ */
36969
+ ExtractSpec.prototype.project = "";
36970
+
36971
+ /**
36972
+ * ExtractSpec dataset.
36973
+ * @member {string} dataset
36974
+ * @memberof sqlanvil.ExtractSpec
36975
+ * @instance
36976
+ */
36977
+ ExtractSpec.prototype.dataset = "";
36978
+
36979
+ /**
36980
+ * ExtractSpec sourceName.
36981
+ * @member {string} sourceName
36982
+ * @memberof sqlanvil.ExtractSpec
36983
+ * @instance
36984
+ */
36985
+ ExtractSpec.prototype.sourceName = "";
36986
+
36987
+ /**
36988
+ * ExtractSpec billingProject.
36989
+ * @member {string} billingProject
36990
+ * @memberof sqlanvil.ExtractSpec
36991
+ * @instance
36992
+ */
36993
+ ExtractSpec.prototype.billingProject = "";
36994
+
36995
+ /**
36996
+ * ExtractSpec columnTypes.
36997
+ * @member {Object.<string,string>} columnTypes
36998
+ * @memberof sqlanvil.ExtractSpec
36999
+ * @instance
37000
+ */
37001
+ ExtractSpec.prototype.columnTypes = $util.emptyObject;
37002
+
37003
+ /**
37004
+ * Creates a new ExtractSpec instance using the specified properties.
37005
+ * @function create
37006
+ * @memberof sqlanvil.ExtractSpec
37007
+ * @static
37008
+ * @param {sqlanvil.IExtractSpec=} [properties] Properties to set
37009
+ * @returns {sqlanvil.ExtractSpec} ExtractSpec instance
37010
+ */
37011
+ ExtractSpec.create = function create(properties) {
37012
+ return new ExtractSpec(properties);
37013
+ };
37014
+
37015
+ /**
37016
+ * Encodes the specified ExtractSpec message. Does not implicitly {@link sqlanvil.ExtractSpec.verify|verify} messages.
37017
+ * @function encode
37018
+ * @memberof sqlanvil.ExtractSpec
37019
+ * @static
37020
+ * @param {sqlanvil.IExtractSpec} message ExtractSpec message or plain object to encode
37021
+ * @param {$protobuf.Writer} [writer] Writer to encode to
37022
+ * @returns {$protobuf.Writer} Writer
37023
+ */
37024
+ ExtractSpec.encode = function encode(message, writer) {
37025
+ if (!writer)
37026
+ writer = $Writer.create();
37027
+ if (message.connectionName != null && Object.hasOwnProperty.call(message, "connectionName"))
37028
+ writer.uint32(/* id 1, wireType 2 =*/10).string(message.connectionName);
37029
+ if (message.platform != null && Object.hasOwnProperty.call(message, "platform"))
37030
+ writer.uint32(/* id 2, wireType 2 =*/18).string(message.platform);
37031
+ if (message.project != null && Object.hasOwnProperty.call(message, "project"))
37032
+ writer.uint32(/* id 3, wireType 2 =*/26).string(message.project);
37033
+ if (message.dataset != null && Object.hasOwnProperty.call(message, "dataset"))
37034
+ writer.uint32(/* id 4, wireType 2 =*/34).string(message.dataset);
37035
+ if (message.sourceName != null && Object.hasOwnProperty.call(message, "sourceName"))
37036
+ writer.uint32(/* id 5, wireType 2 =*/42).string(message.sourceName);
37037
+ if (message.billingProject != null && Object.hasOwnProperty.call(message, "billingProject"))
37038
+ writer.uint32(/* id 6, wireType 2 =*/50).string(message.billingProject);
37039
+ if (message.columnTypes != null && Object.hasOwnProperty.call(message, "columnTypes"))
37040
+ for (let keys = Object.keys(message.columnTypes), i = 0; i < keys.length; ++i)
37041
+ writer.uint32(/* id 7, wireType 2 =*/58).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.columnTypes[keys[i]]).ldelim();
37042
+ return writer;
37043
+ };
37044
+
37045
+ /**
37046
+ * Encodes the specified ExtractSpec message, length delimited. Does not implicitly {@link sqlanvil.ExtractSpec.verify|verify} messages.
37047
+ * @function encodeDelimited
37048
+ * @memberof sqlanvil.ExtractSpec
37049
+ * @static
37050
+ * @param {sqlanvil.IExtractSpec} message ExtractSpec message or plain object to encode
37051
+ * @param {$protobuf.Writer} [writer] Writer to encode to
37052
+ * @returns {$protobuf.Writer} Writer
37053
+ */
37054
+ ExtractSpec.encodeDelimited = function encodeDelimited(message, writer) {
37055
+ return this.encode(message, writer).ldelim();
37056
+ };
37057
+
37058
+ /**
37059
+ * Decodes an ExtractSpec message from the specified reader or buffer.
37060
+ * @function decode
37061
+ * @memberof sqlanvil.ExtractSpec
37062
+ * @static
37063
+ * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
37064
+ * @param {number} [length] Message length if known beforehand
37065
+ * @returns {sqlanvil.ExtractSpec} ExtractSpec
37066
+ * @throws {Error} If the payload is not a reader or valid buffer
37067
+ * @throws {$protobuf.util.ProtocolError} If required fields are missing
37068
+ */
37069
+ ExtractSpec.decode = function decode(reader, length, error, long) {
37070
+ if (!(reader instanceof $Reader))
37071
+ reader = $Reader.create(reader);
37072
+ if (long === undefined)
37073
+ long = 0;
37074
+ if (long > $Reader.recursionLimit)
37075
+ throw Error("maximum nesting depth exceeded");
37076
+ let end = length === undefined ? reader.len : reader.pos + length, message = new $root.sqlanvil.ExtractSpec(), key, value;
37077
+ while (reader.pos < end) {
37078
+ let tag = reader.uint32();
37079
+ if (tag === error)
37080
+ break;
37081
+ switch (tag >>> 3) {
37082
+ case 1: {
37083
+ message.connectionName = reader.string();
37084
+ break;
37085
+ }
37086
+ case 2: {
37087
+ message.platform = reader.string();
37088
+ break;
37089
+ }
37090
+ case 3: {
37091
+ message.project = reader.string();
37092
+ break;
37093
+ }
37094
+ case 4: {
37095
+ message.dataset = reader.string();
37096
+ break;
37097
+ }
37098
+ case 5: {
37099
+ message.sourceName = reader.string();
37100
+ break;
37101
+ }
37102
+ case 6: {
37103
+ message.billingProject = reader.string();
37104
+ break;
37105
+ }
37106
+ case 7: {
37107
+ if (message.columnTypes === $util.emptyObject)
37108
+ message.columnTypes = {};
37109
+ let end2 = reader.uint32() + reader.pos;
37110
+ key = "";
37111
+ value = "";
37112
+ while (reader.pos < end2) {
37113
+ let tag2 = reader.uint32();
37114
+ switch (tag2 >>> 3) {
37115
+ case 1:
37116
+ key = reader.string();
37117
+ break;
37118
+ case 2:
37119
+ value = reader.string();
37120
+ break;
37121
+ default:
37122
+ reader.skipType(tag2 & 7, long);
37123
+ break;
37124
+ }
37125
+ }
37126
+ if (key === "__proto__")
37127
+ $util.makeProp(message.columnTypes, key);
37128
+ message.columnTypes[key] = value;
37129
+ break;
37130
+ }
37131
+ default:
37132
+ reader.skipType(tag & 7, long);
37133
+ break;
37134
+ }
37135
+ }
37136
+ return message;
37137
+ };
37138
+
37139
+ /**
37140
+ * Decodes an ExtractSpec message from the specified reader or buffer, length delimited.
37141
+ * @function decodeDelimited
37142
+ * @memberof sqlanvil.ExtractSpec
37143
+ * @static
37144
+ * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
37145
+ * @returns {sqlanvil.ExtractSpec} ExtractSpec
37146
+ * @throws {Error} If the payload is not a reader or valid buffer
37147
+ * @throws {$protobuf.util.ProtocolError} If required fields are missing
37148
+ */
37149
+ ExtractSpec.decodeDelimited = function decodeDelimited(reader) {
37150
+ if (!(reader instanceof $Reader))
37151
+ reader = new $Reader(reader);
37152
+ return this.decode(reader, reader.uint32());
37153
+ };
37154
+
37155
+ /**
37156
+ * Verifies an ExtractSpec message.
37157
+ * @function verify
37158
+ * @memberof sqlanvil.ExtractSpec
37159
+ * @static
37160
+ * @param {Object.<string,*>} message Plain object to verify
37161
+ * @returns {string|null} `null` if valid, otherwise the reason why it is not
37162
+ */
37163
+ ExtractSpec.verify = function verify(message, long) {
37164
+ if (typeof message !== "object" || message === null)
37165
+ return "object expected";
37166
+ if (long === undefined)
37167
+ long = 0;
37168
+ if (long > $util.recursionLimit)
37169
+ return "maximum nesting depth exceeded";
37170
+ if (message.connectionName != null && message.hasOwnProperty("connectionName"))
37171
+ if (!$util.isString(message.connectionName))
37172
+ return "connectionName: string expected";
37173
+ if (message.platform != null && message.hasOwnProperty("platform"))
37174
+ if (!$util.isString(message.platform))
37175
+ return "platform: string expected";
37176
+ if (message.project != null && message.hasOwnProperty("project"))
37177
+ if (!$util.isString(message.project))
37178
+ return "project: string expected";
37179
+ if (message.dataset != null && message.hasOwnProperty("dataset"))
37180
+ if (!$util.isString(message.dataset))
37181
+ return "dataset: string expected";
37182
+ if (message.sourceName != null && message.hasOwnProperty("sourceName"))
37183
+ if (!$util.isString(message.sourceName))
37184
+ return "sourceName: string expected";
37185
+ if (message.billingProject != null && message.hasOwnProperty("billingProject"))
37186
+ if (!$util.isString(message.billingProject))
37187
+ return "billingProject: string expected";
37188
+ if (message.columnTypes != null && message.hasOwnProperty("columnTypes")) {
37189
+ if (!$util.isObject(message.columnTypes))
37190
+ return "columnTypes: object expected";
37191
+ let key = Object.keys(message.columnTypes);
37192
+ for (let i = 0; i < key.length; ++i)
37193
+ if (!$util.isString(message.columnTypes[key[i]]))
37194
+ return "columnTypes: string{k:string} expected";
37195
+ }
37196
+ return null;
37197
+ };
37198
+
37199
+ /**
37200
+ * Creates an ExtractSpec message from a plain object. Also converts values to their respective internal types.
37201
+ * @function fromObject
37202
+ * @memberof sqlanvil.ExtractSpec
37203
+ * @static
37204
+ * @param {Object.<string,*>} object Plain object
37205
+ * @returns {sqlanvil.ExtractSpec} ExtractSpec
37206
+ */
37207
+ ExtractSpec.fromObject = function fromObject(object, long) {
37208
+ if (object instanceof $root.sqlanvil.ExtractSpec)
37209
+ return object;
37210
+ if (long === undefined)
37211
+ long = 0;
37212
+ if (long > $util.recursionLimit)
37213
+ throw Error("maximum nesting depth exceeded");
37214
+ let message = new $root.sqlanvil.ExtractSpec();
37215
+ if (object.connectionName != null)
37216
+ message.connectionName = String(object.connectionName);
37217
+ if (object.platform != null)
37218
+ message.platform = String(object.platform);
37219
+ if (object.project != null)
37220
+ message.project = String(object.project);
37221
+ if (object.dataset != null)
37222
+ message.dataset = String(object.dataset);
37223
+ if (object.sourceName != null)
37224
+ message.sourceName = String(object.sourceName);
37225
+ if (object.billingProject != null)
37226
+ message.billingProject = String(object.billingProject);
37227
+ if (object.columnTypes) {
37228
+ if (typeof object.columnTypes !== "object")
37229
+ throw TypeError(".sqlanvil.ExtractSpec.columnTypes: object expected");
37230
+ message.columnTypes = {};
37231
+ for (let keys = Object.keys(object.columnTypes), i = 0; i < keys.length; ++i) {
37232
+ if (keys[i] === "__proto__")
37233
+ $util.makeProp(message.columnTypes, keys[i]);
37234
+ message.columnTypes[keys[i]] = String(object.columnTypes[keys[i]]);
37235
+ }
37236
+ }
37237
+ return message;
37238
+ };
37239
+
37240
+ /**
37241
+ * Creates a plain object from an ExtractSpec message. Also converts values to other types if specified.
37242
+ * @function toObject
37243
+ * @memberof sqlanvil.ExtractSpec
37244
+ * @static
37245
+ * @param {sqlanvil.ExtractSpec} message ExtractSpec
37246
+ * @param {$protobuf.IConversionOptions} [options] Conversion options
37247
+ * @returns {Object.<string,*>} Plain object
37248
+ */
37249
+ ExtractSpec.toObject = function toObject(message, options) {
37250
+ if (!options)
37251
+ options = {};
37252
+ let object = {};
37253
+ if (options.objects || options.defaults)
37254
+ object.columnTypes = {};
37255
+ if (options.defaults) {
37256
+ object.connectionName = "";
37257
+ object.platform = "";
37258
+ object.project = "";
37259
+ object.dataset = "";
37260
+ object.sourceName = "";
37261
+ object.billingProject = "";
37262
+ }
37263
+ if (message.connectionName != null && message.hasOwnProperty("connectionName"))
37264
+ object.connectionName = message.connectionName;
37265
+ if (message.platform != null && message.hasOwnProperty("platform"))
37266
+ object.platform = message.platform;
37267
+ if (message.project != null && message.hasOwnProperty("project"))
37268
+ object.project = message.project;
37269
+ if (message.dataset != null && message.hasOwnProperty("dataset"))
37270
+ object.dataset = message.dataset;
37271
+ if (message.sourceName != null && message.hasOwnProperty("sourceName"))
37272
+ object.sourceName = message.sourceName;
37273
+ if (message.billingProject != null && message.hasOwnProperty("billingProject"))
37274
+ object.billingProject = message.billingProject;
37275
+ let keys2;
37276
+ if (message.columnTypes && (keys2 = Object.keys(message.columnTypes)).length) {
37277
+ object.columnTypes = {};
37278
+ for (let j = 0; j < keys2.length; ++j) {
37279
+ if (keys2[j] === "__proto__")
37280
+ $util.makeProp(object.columnTypes, keys2[j]);
37281
+ object.columnTypes[keys2[j]] = message.columnTypes[keys2[j]];
37282
+ }
37283
+ }
37284
+ return object;
37285
+ };
37286
+
37287
+ /**
37288
+ * Converts this ExtractSpec to JSON.
37289
+ * @function toJSON
37290
+ * @memberof sqlanvil.ExtractSpec
37291
+ * @instance
37292
+ * @returns {Object.<string,*>} JSON object
37293
+ */
37294
+ ExtractSpec.prototype.toJSON = function toJSON() {
37295
+ return this.constructor.toObject(this, $protobuf__namespace.util.toJSONOptions);
37296
+ };
37297
+
37298
+ /**
37299
+ * Gets the default type url for ExtractSpec
37300
+ * @function getTypeUrl
37301
+ * @memberof sqlanvil.ExtractSpec
37302
+ * @static
37303
+ * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
37304
+ * @returns {string} The default type url
37305
+ */
37306
+ ExtractSpec.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
37307
+ if (typeUrlPrefix === undefined) {
37308
+ typeUrlPrefix = "type.googleapis.com";
37309
+ }
37310
+ return typeUrlPrefix + "/sqlanvil.ExtractSpec";
37311
+ };
37312
+
37313
+ return ExtractSpec;
37314
+ })();
37315
+
36186
37316
  sqlanvil.ExecutionAction = (function() {
36187
37317
 
36188
37318
  /**
@@ -36200,6 +37330,7 @@ const sqlanvil = $root.sqlanvil = (() => {
36200
37330
  * @property {string|null} [jitCode] ExecutionAction jitCode
36201
37331
  * @property {sqlanvil.IExportSpec|null} ["export"] ExecutionAction export
36202
37332
  * @property {sqlanvil.IImportSpec|null} ["import"] ExecutionAction import
37333
+ * @property {sqlanvil.IExtractSpec|null} [extract] ExecutionAction extract
36203
37334
  */
36204
37335
 
36205
37336
  /**
@@ -36307,6 +37438,14 @@ const sqlanvil = $root.sqlanvil = (() => {
36307
37438
  */
36308
37439
  ExecutionAction.prototype["import"] = null;
36309
37440
 
37441
+ /**
37442
+ * ExecutionAction extract.
37443
+ * @member {sqlanvil.IExtractSpec|null|undefined} extract
37444
+ * @memberof sqlanvil.ExecutionAction
37445
+ * @instance
37446
+ */
37447
+ ExecutionAction.prototype.extract = null;
37448
+
36310
37449
  /**
36311
37450
  * Creates a new ExecutionAction instance using the specified properties.
36312
37451
  * @function create
@@ -36355,6 +37494,8 @@ const sqlanvil = $root.sqlanvil = (() => {
36355
37494
  $root.sqlanvil.ExportSpec.encode(message["export"], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
36356
37495
  if (message["import"] != null && Object.hasOwnProperty.call(message, "import"))
36357
37496
  $root.sqlanvil.ImportSpec.encode(message["import"], writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
37497
+ if (message.extract != null && Object.hasOwnProperty.call(message, "extract"))
37498
+ $root.sqlanvil.ExtractSpec.encode(message.extract, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
36358
37499
  return writer;
36359
37500
  };
36360
37501
 
@@ -36443,6 +37584,10 @@ const sqlanvil = $root.sqlanvil = (() => {
36443
37584
  message["import"] = $root.sqlanvil.ImportSpec.decode(reader, reader.uint32(), undefined, long + 1);
36444
37585
  break;
36445
37586
  }
37587
+ case 15: {
37588
+ message.extract = $root.sqlanvil.ExtractSpec.decode(reader, reader.uint32(), undefined, long + 1);
37589
+ break;
37590
+ }
36446
37591
  default:
36447
37592
  reader.skipType(tag & 7, long);
36448
37593
  break;
@@ -36541,6 +37686,11 @@ const sqlanvil = $root.sqlanvil = (() => {
36541
37686
  if (error)
36542
37687
  return "import." + error;
36543
37688
  }
37689
+ if (message.extract != null && message.hasOwnProperty("extract")) {
37690
+ let error = $root.sqlanvil.ExtractSpec.verify(message.extract, long + 1);
37691
+ if (error)
37692
+ return "extract." + error;
37693
+ }
36544
37694
  return null;
36545
37695
  };
36546
37696
 
@@ -36628,6 +37778,11 @@ const sqlanvil = $root.sqlanvil = (() => {
36628
37778
  throw TypeError(".sqlanvil.ExecutionAction.import: object expected");
36629
37779
  message["import"] = $root.sqlanvil.ImportSpec.fromObject(object["import"], long + 1);
36630
37780
  }
37781
+ if (object.extract != null) {
37782
+ if (typeof object.extract !== "object")
37783
+ throw TypeError(".sqlanvil.ExecutionAction.extract: object expected");
37784
+ message.extract = $root.sqlanvil.ExtractSpec.fromObject(object.extract, long + 1);
37785
+ }
36631
37786
  return message;
36632
37787
  };
36633
37788
 
@@ -36658,6 +37813,7 @@ const sqlanvil = $root.sqlanvil = (() => {
36658
37813
  object.jitCode = "";
36659
37814
  object["export"] = null;
36660
37815
  object["import"] = null;
37816
+ object.extract = null;
36661
37817
  }
36662
37818
  if (message.tasks && message.tasks.length) {
36663
37819
  object.tasks = [];
@@ -36687,6 +37843,8 @@ const sqlanvil = $root.sqlanvil = (() => {
36687
37843
  object["export"] = $root.sqlanvil.ExportSpec.toObject(message["export"], options);
36688
37844
  if (message["import"] != null && message.hasOwnProperty("import"))
36689
37845
  object["import"] = $root.sqlanvil.ImportSpec.toObject(message["import"], options);
37846
+ if (message.extract != null && message.hasOwnProperty("extract"))
37847
+ object.extract = $root.sqlanvil.ExtractSpec.toObject(message.extract, options);
36690
37848
  return object;
36691
37849
  };
36692
37850
 
@@ -43305,6 +44463,7 @@ const sqlanvil = $root.sqlanvil = (() => {
43305
44463
  * @property {string|null} [projectId] BigQuery projectId
43306
44464
  * @property {string|null} [credentials] BigQuery credentials
43307
44465
  * @property {string|null} [location] BigQuery location
44466
+ * @property {string|null} [accessToken] BigQuery accessToken
43308
44467
  */
43309
44468
 
43310
44469
  /**
@@ -43346,6 +44505,14 @@ const sqlanvil = $root.sqlanvil = (() => {
43346
44505
  */
43347
44506
  BigQuery.prototype.location = "";
43348
44507
 
44508
+ /**
44509
+ * BigQuery accessToken.
44510
+ * @member {string} accessToken
44511
+ * @memberof sqlanvil.BigQuery
44512
+ * @instance
44513
+ */
44514
+ BigQuery.prototype.accessToken = "";
44515
+
43349
44516
  /**
43350
44517
  * Creates a new BigQuery instance using the specified properties.
43351
44518
  * @function create
@@ -43376,6 +44543,8 @@ const sqlanvil = $root.sqlanvil = (() => {
43376
44543
  writer.uint32(/* id 3, wireType 2 =*/26).string(message.credentials);
43377
44544
  if (message.location != null && Object.hasOwnProperty.call(message, "location"))
43378
44545
  writer.uint32(/* id 4, wireType 2 =*/34).string(message.location);
44546
+ if (message.accessToken != null && Object.hasOwnProperty.call(message, "accessToken"))
44547
+ writer.uint32(/* id 5, wireType 2 =*/42).string(message.accessToken);
43379
44548
  return writer;
43380
44549
  };
43381
44550
 
@@ -43428,6 +44597,10 @@ const sqlanvil = $root.sqlanvil = (() => {
43428
44597
  message.location = reader.string();
43429
44598
  break;
43430
44599
  }
44600
+ case 5: {
44601
+ message.accessToken = reader.string();
44602
+ break;
44603
+ }
43431
44604
  default:
43432
44605
  reader.skipType(tag & 7, long);
43433
44606
  break;
@@ -43476,6 +44649,9 @@ const sqlanvil = $root.sqlanvil = (() => {
43476
44649
  if (message.location != null && message.hasOwnProperty("location"))
43477
44650
  if (!$util.isString(message.location))
43478
44651
  return "location: string expected";
44652
+ if (message.accessToken != null && message.hasOwnProperty("accessToken"))
44653
+ if (!$util.isString(message.accessToken))
44654
+ return "accessToken: string expected";
43479
44655
  return null;
43480
44656
  };
43481
44657
 
@@ -43501,6 +44677,8 @@ const sqlanvil = $root.sqlanvil = (() => {
43501
44677
  message.credentials = String(object.credentials);
43502
44678
  if (object.location != null)
43503
44679
  message.location = String(object.location);
44680
+ if (object.accessToken != null)
44681
+ message.accessToken = String(object.accessToken);
43504
44682
  return message;
43505
44683
  };
43506
44684
 
@@ -43521,6 +44699,7 @@ const sqlanvil = $root.sqlanvil = (() => {
43521
44699
  object.projectId = "";
43522
44700
  object.credentials = "";
43523
44701
  object.location = "";
44702
+ object.accessToken = "";
43524
44703
  }
43525
44704
  if (message.projectId != null && message.hasOwnProperty("projectId"))
43526
44705
  object.projectId = message.projectId;
@@ -43528,6 +44707,8 @@ const sqlanvil = $root.sqlanvil = (() => {
43528
44707
  object.credentials = message.credentials;
43529
44708
  if (message.location != null && message.hasOwnProperty("location"))
43530
44709
  object.location = message.location;
44710
+ if (message.accessToken != null && message.hasOwnProperty("accessToken"))
44711
+ object.accessToken = message.accessToken;
43531
44712
  return object;
43532
44713
  };
43533
44714
 
@@ -46342,7 +47523,7 @@ function collectEvaluationQueries(queryOrAction, concatenate, queryModifier = (q
46342
47523
  .filter(validationQuery => !!validationQuery.query);
46343
47524
  }
46344
47525
 
46345
- const version = "1.13.0";
47526
+ const version = "1.15.0";
46346
47527
  const dataformVersion = "3.0.60";
46347
47528
 
46348
47529
  async function build(compiledGraph, runConfig, dbadapter) {
@@ -46366,7 +47547,7 @@ class Builder {
46366
47547
  this.warehouseState.tables.forEach(tableState => {
46367
47548
  tableMetadataByTarget.set(targetStringifier.stringify(tableState.target), tableState);
46368
47549
  });
46369
- const actions = [].concat(this.prunedGraph.tables.map(t => this.buildTable(t, tableMetadataByTarget.get(targetStringifier.stringify(t.target)), this.runConfig)), this.prunedGraph.operations.map(o => this.buildOperation(o)), this.prunedGraph.assertions.map(a => this.buildAssertion(a)), this.prunedGraph.exports.map(e => this.buildExport(e)), this.prunedGraph.imports.map(i => this.buildImport(i)));
47550
+ const actions = [].concat(this.prunedGraph.tables.map(t => this.buildTable(t, tableMetadataByTarget.get(targetStringifier.stringify(t.target)), this.runConfig)), this.prunedGraph.operations.map(o => this.buildOperation(o)), this.prunedGraph.assertions.map(a => this.buildAssertion(a)), this.prunedGraph.exports.map(e => this.buildExport(e)), this.prunedGraph.imports.map(i => this.buildImport(i)), this.prunedGraph.extracts.map(e => this.buildExtract(e)));
46370
47551
  return sqlanvil.ExecutionGraph.create({
46371
47552
  projectConfig: this.prunedGraph.projectConfig,
46372
47553
  runConfig: this.runConfig,
@@ -46402,6 +47583,17 @@ class Builder {
46402
47583
  options: imp.options
46403
47584
  }) });
46404
47585
  }
47586
+ buildExtract(ext) {
47587
+ return Object.assign(Object.assign({}, this.toPartialExecutionAction(ext)), { type: "extract", tasks: ext.disabled ? [] : [sqlanvil.ExecutionTask.create({ type: "extract", statement: "" })], hermeticity: ext.hermeticity || sqlanvil.ActionHermeticity.NON_HERMETIC, extract: sqlanvil.ExtractSpec.create({
47588
+ connectionName: ext.connectionName,
47589
+ platform: ext.platform,
47590
+ project: ext.project,
47591
+ dataset: ext.dataset,
47592
+ sourceName: ext.sourceName,
47593
+ billingProject: ext.billingProject,
47594
+ columnTypes: ext.columnTypes
47595
+ }) });
47596
+ }
46405
47597
  toPartialExecutionAction(action) {
46406
47598
  return sqlanvil.ExecutionAction.create({
46407
47599
  target: action.target,
@@ -47061,319 +48253,1250 @@ function assertConnectionCredentialsAvailable(graph, connections) {
47061
48253
  }));
47062
48254
  }
47063
48255
 
47064
- function loadDuckdb() {
47065
- try {
47066
- return nativeRequire("@duckdb/node-api");
47067
- }
47068
- catch (e) {
47069
- throw new Error(`This feature requires the optional "@duckdb/node-api" dependency, which failed to load: ` +
47070
- `${e.message}`);
47071
- }
47072
- }
47073
- async function runAsync(conn, sql) {
47074
- await conn.run(sql);
47075
- }
47076
- async function allAsync(conn, sql) {
47077
- const reader = await conn.runAndReadAll(sql);
47078
- return reader.getRowObjects();
48256
+ function parsePostgresEvalError(_query, error) {
48257
+ return sqlanvil.QueryEvaluationError.create({
48258
+ message: (error === null || error === void 0 ? void 0 : error.message) ? String(error.message) : String(error)
48259
+ });
47079
48260
  }
47080
- async function withDuckdb(fn, dbPath = ":memory:") {
47081
- const { DuckDBInstance } = loadDuckdb();
47082
- const instance = await DuckDBInstance.create(dbPath);
47083
- const conn = await instance.connect();
47084
- const done = () => {
47085
- var _a, _b;
47086
- try {
47087
- (_a = conn.closeSync) === null || _a === void 0 ? void 0 : _a.call(conn);
47088
- }
47089
- catch (e) {
47090
- }
47091
- try {
47092
- (_b = instance.closeSync) === null || _b === void 0 ? void 0 : _b.call(instance);
47093
- }
47094
- catch (e) {
47095
- }
47096
- };
48261
+ function parseBigqueryEvalError(error) {
48262
+ const evalError = sqlanvil.QueryEvaluationError.create({
48263
+ message: String(error)
48264
+ });
47097
48265
  try {
47098
- if (!process.env.HOME) {
47099
- await runAsync(conn, `SET home_directory='${os__namespace.tmpdir()}'`);
48266
+ if (!error.message) {
48267
+ return evalError;
48268
+ }
48269
+ const bracketsString = error.message.split("[").slice(-1)[0];
48270
+ const [_, lineNumber, columnNumber] = bracketsString.match(/([0-9]*)[^0-9]*([0-9]*).*/);
48271
+ const line = Number(lineNumber);
48272
+ const column = Number(columnNumber);
48273
+ if (line || line === 0) {
48274
+ evalError.errorLocation = { line, column };
47100
48275
  }
47101
- const result = await fn(conn);
47102
- done();
47103
- return result;
47104
48276
  }
47105
- catch (e) {
47106
- done();
47107
- throw e;
48277
+ catch (_) {
47108
48278
  }
48279
+ return evalError;
47109
48280
  }
47110
48281
 
47111
- const PG_ATTACH_ALIAS = "pg";
47112
- const SECRET_NAME = "sa_export";
47113
- function buildAttachSql(pg, opts = {}) {
47114
- const readOnly = opts.readOnly !== false;
47115
- const dsn = [
47116
- pg.host && `host=${pg.host}`,
47117
- pg.port && `port=${pg.port}`,
47118
- pg.database && `dbname=${pg.database}`,
47119
- pg.user && `user=${pg.user}`,
47120
- pg.password && `password=${pg.password}`
47121
- ]
47122
- .filter(Boolean)
47123
- .join(" ");
47124
- const mode = readOnly ? ", READ_ONLY" : "";
47125
- return `ATTACH '${dsn}' AS ${PG_ATTACH_ALIAS} (TYPE postgres${mode})`;
47126
- }
47127
- function buildSecretSql(scheme, creds) {
47128
- if (scheme === "s3") {
47129
- const fields = [
47130
- "TYPE s3",
47131
- creds.accessKeyId && `KEY_ID '${creds.accessKeyId}'`,
47132
- creds.secretAccessKey && `SECRET '${creds.secretAccessKey}'`,
47133
- creds.region && `REGION '${creds.region}'`,
47134
- creds.endpoint && `ENDPOINT '${creds.endpoint}'`,
47135
- creds.endpoint && `URL_STYLE 'path'`,
47136
- creds.endpoint && `USE_SSL true`
47137
- ]
47138
- .filter(Boolean)
47139
- .join(", ");
47140
- return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
47141
- }
47142
- if (scheme === "gcs") {
47143
- const fields = [
47144
- "TYPE gcs",
47145
- creds.keyId && `KEY_ID '${creds.keyId}'`,
47146
- creds.secret && `SECRET '${creds.secret}'`
47147
- ]
47148
- .filter(Boolean)
47149
- .join(", ");
47150
- return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
47151
- }
47152
- return null;
47153
- }
47154
- function toCopyTarget(uri) {
47155
- if (uri.startsWith("local://")) {
47156
- return uri.slice("local://".length);
48282
+ class LimitedResultSet {
48283
+ constructor(options) {
48284
+ this.options = options;
48285
+ this.results = [];
48286
+ this.currentBytes = 0;
47157
48287
  }
47158
- return uri;
47159
- }
47160
- function schemeOf(uri) {
47161
- if (uri.startsWith("s3://")) {
47162
- return "s3";
48288
+ push(row) {
48289
+ var _a, _b, _c, _d;
48290
+ this.currentBytes += sizeof__default["default"](row);
48291
+ if ((((_a = this.options) === null || _a === void 0 ? void 0 : _a.rowLimit) && this.results.length >= ((_b = this.options) === null || _b === void 0 ? void 0 : _b.rowLimit)) ||
48292
+ (((_c = this.options) === null || _c === void 0 ? void 0 : _c.byteLimit) && this.currentBytes >= ((_d = this.options) === null || _d === void 0 ? void 0 : _d.byteLimit))) {
48293
+ return false;
48294
+ }
48295
+ this.results.push(row);
48296
+ return true;
47163
48297
  }
47164
- if (uri.startsWith("gs://") || uri.startsWith("gcs://")) {
47165
- return "gcs";
48298
+ get rows() {
48299
+ return this.results;
47166
48300
  }
47167
- return "local";
47168
- }
47169
- function buildCopySql(selectSql, uri, format, options = {}) {
47170
- const target = toCopyTarget(uri);
47171
- const fmt = (format || "").toLowerCase();
47172
- const extraOptions = Object.entries(options || {}).map(([key, value]) => `${key.toUpperCase()} ${value}`);
47173
- const optionList = [`FORMAT ${fmt}`, ...extraOptions].join(", ");
47174
- return `COPY (SELECT * FROM postgres_query('${PG_ATTACH_ALIAS}', $sa$${selectSql}$sa$)) TO '${target}' (${optionList})`;
47175
48301
  }
47176
- async function runDuckdbExport(args) {
47177
- const { spec, selectSql, pg, storage, actionName } = args;
47178
- const uri = resolveExportUri(spec, actionName, { wildcard: false });
47179
- const scheme = schemeOf(uri);
47180
- if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
47181
- throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
47182
- `export to ${uri}.`);
47183
- }
47184
- return withDuckdb(async (conn) => {
47185
- await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
47186
- await runAsync(conn, buildAttachSql(pg));
47187
- if (scheme !== "local") {
47188
- const secret = buildSecretSql(scheme, storage[scheme]);
47189
- if (secret) {
47190
- await runAsync(conn, secret);
48302
+
48303
+ async function retry(fn, maxAttempts = 1, matchesRetriableError = () => true) {
48304
+ let lastErr;
48305
+ for (let i = 0; i < maxAttempts; i++) {
48306
+ try {
48307
+ return await fn();
48308
+ }
48309
+ catch (e) {
48310
+ if (!matchesRetriableError(e)) {
48311
+ throw e;
47191
48312
  }
48313
+ lastErr = e;
47192
48314
  }
47193
- await runAsync(conn, buildCopySql(selectSql, uri, spec.format, spec.options || {}));
47194
- return { destination: toCopyTarget(uri) };
47195
- });
47196
- }
47197
-
47198
- function readerForFormat(format) {
47199
- switch ((format || "").toLowerCase()) {
47200
- case "csv":
47201
- return "read_csv_auto";
47202
- case "json":
47203
- return "read_json_auto";
47204
- case "parquet":
47205
- default:
47206
- return "read_parquet";
47207
48315
  }
48316
+ throw lastErr;
47208
48317
  }
47209
- function importTargetSql(target) {
47210
- return target.schema
47211
- ? `${PG_ATTACH_ALIAS}."${target.schema}"."${target.name}"`
47212
- : `${PG_ATTACH_ALIAS}."${target.name}"`;
47213
- }
47214
- function buildImportSql(target, location, format, overwrite) {
47215
- const reader = readerForFormat(format);
47216
- const source = toCopyTarget(location);
47217
- const dest = importTargetSql(target);
47218
- const select = `SELECT * FROM ${reader}('${source}')`;
47219
- if (overwrite) {
47220
- return [`DROP TABLE IF EXISTS ${dest}`, `CREATE TABLE ${dest} AS ${select}`];
48318
+
48319
+ const EXTRA_GOOGLE_SCOPES = ["https://www.googleapis.com/auth/drive"];
48320
+ function bigQueryClientOptions(credentials, projectId) {
48321
+ const base = {
48322
+ projectId,
48323
+ scopes: EXTRA_GOOGLE_SCOPES,
48324
+ location: credentials.location || undefined
48325
+ };
48326
+ if (credentials.accessToken) {
48327
+ const authClient = new googleAuthLibrary.OAuth2Client();
48328
+ authClient.setCredentials({ access_token: credentials.accessToken });
48329
+ return Object.assign(Object.assign({}, base), { authClient: authClient });
47221
48330
  }
47222
- return [`INSERT INTO ${dest} ${select}`];
48331
+ return Object.assign(Object.assign({}, base), { credentials: credentials.credentials ? JSON.parse(credentials.credentials) : undefined });
47223
48332
  }
47224
- async function runDuckdbImport(args) {
47225
- const { spec, target, pg, storage } = args;
47226
- const location = spec.location || "";
47227
- const scheme = schemeOf(location);
47228
- if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
47229
- throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
47230
- `import from ${location}.`);
48333
+ const BIGQUERY_DATE_RELATED_FIELDS = [
48334
+ "BigQueryDate",
48335
+ "BigQueryTime",
48336
+ "BigQueryTimestamp",
48337
+ "BigQueryDatetime"
48338
+ ];
48339
+ const BIGQUERY_INTERNAL_ERROR_JOB_MAX_ATTEMPTS = 3;
48340
+ class BigQueryDbAdapter {
48341
+ constructor(credentials, options) {
48342
+ this.clients = new Map();
48343
+ this.bigQueryCredentials = credentials;
48344
+ this.bigqueryClient = options === null || options === void 0 ? void 0 : options.bigqueryClient;
48345
+ this.pool = new promisePoolExecutor.PromisePoolExecutor({
48346
+ concurrencyLimit: options === null || options === void 0 ? void 0 : options.concurrencyLimit,
48347
+ frequencyWindow: 1000,
48348
+ frequencyLimit: 30
48349
+ });
47231
48350
  }
47232
- return withDuckdb(async (conn) => {
47233
- await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
47234
- await runAsync(conn, buildAttachSql(pg, { readOnly: false }));
47235
- if (scheme !== "local") {
47236
- const secret = buildSecretSql(scheme, storage[scheme]);
47237
- if (secret) {
47238
- await runAsync(conn, secret);
47239
- }
47240
- }
47241
- for (const statement of buildImportSql(target, location, spec.format, spec.overwrite)) {
47242
- await runAsync(conn, statement);
47243
- }
47244
- return { source: toCopyTarget(location) };
47245
- });
47246
- }
47247
-
47248
- function parseArgvFlags(argv) {
47249
- const parsedArgv = {};
47250
- const splitArgv = [];
47251
- for (let arg of argv) {
47252
- if (arg.startsWith("--no-")) {
47253
- arg = `--${arg.slice(5)}=false`;
47254
- }
47255
- if (arg.startsWith("--") && arg.includes("=")) {
47256
- splitArgv.push(arg.slice(0, arg.indexOf("=")));
47257
- splitArgv.push(arg.slice(arg.indexOf("=") + 1));
48351
+ async execute(statement, options = { interactive: false, rowLimit: 1000, byteLimit: 1024 * 1024 }) {
48352
+ var _a;
48353
+ if ((options === null || options === void 0 ? void 0 : options.interactive) && ((_a = options === null || options === void 0 ? void 0 : options.bigquery) === null || _a === void 0 ? void 0 : _a.labels)) {
48354
+ throw new Error("BigQuery job labels may not be set for interactive queries.");
47258
48355
  }
47259
- else {
47260
- splitArgv.push(arg);
48356
+ if (!statement) {
48357
+ throw new Error("Query string cannot be empty");
47261
48358
  }
48359
+ return this.pool
48360
+ .addSingleTask({
48361
+ generator: () => {
48362
+ var _a, _b, _c, _d, _e, _f;
48363
+ return (options === null || options === void 0 ? void 0 : options.interactive) ? this.runQuery(statement, options === null || options === void 0 ? void 0 : options.params, options === null || options === void 0 ? void 0 : options.rowLimit, options === null || options === void 0 ? void 0 : options.byteLimit, (_a = options.bigquery) === null || _a === void 0 ? void 0 : _a.location)
48364
+ : this.createQueryJob(statement, options === null || options === void 0 ? void 0 : options.params, options === null || options === void 0 ? void 0 : options.rowLimit, options === null || options === void 0 ? void 0 : options.byteLimit, options === null || options === void 0 ? void 0 : options.onCancel, (_b = options === null || options === void 0 ? void 0 : options.bigquery) === null || _b === void 0 ? void 0 : _b.labels, (_c = options === null || options === void 0 ? void 0 : options.bigquery) === null || _c === void 0 ? void 0 : _c.location, (_d = options === null || options === void 0 ? void 0 : options.bigquery) === null || _d === void 0 ? void 0 : _d.jobPrefix, (_e = options === null || options === void 0 ? void 0 : options.bigquery) === null || _e === void 0 ? void 0 : _e.dryRun, (_f = options === null || options === void 0 ? void 0 : options.bigquery) === null || _f === void 0 ? void 0 : _f.reservation);
48365
+ }
48366
+ })
48367
+ .promise();
47262
48368
  }
47263
- let currentFlagName = "";
47264
- for (const splitArg of splitArgv) {
47265
- if (splitArg.startsWith("--")) {
47266
- currentFlagName = splitArg.slice(2);
47267
- parsedArgv[currentFlagName] = "";
47268
- }
47269
- else if (currentFlagName) {
47270
- parsedArgv[currentFlagName] = splitArg;
47271
- currentFlagName = "";
48369
+ async executeRaw(statement, options = { rowLimit: 1000 }) {
48370
+ if (!statement) {
48371
+ throw new Error("Query string cannot be empty");
47272
48372
  }
47273
- }
47274
- return parsedArgv;
47275
- }
47276
- class Flags {
47277
- static boolean(name, defaultValue = false) {
47278
- return new SingleValueFlag(name, defaultValue, (stringValue) => {
47279
- if (stringValue === "" || stringValue === "true") {
47280
- return true;
47281
- }
47282
- if (stringValue === "false") {
47283
- return false;
48373
+ return this.pool
48374
+ .addSingleTask({
48375
+ generator: async () => {
48376
+ var _a, _b;
48377
+ const [rows, , apiResponse] = await this.getClient().query(Object.assign(Object.assign({}, this.prepareQueryOptions(statement, options.rowLimit, options.bigquery, options.params)), { skipParsing: true }));
48378
+ const schema = (_b = (_a = apiResponse === null || apiResponse === void 0 ? void 0 : apiResponse.schema) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b.map((field) => convertField(field));
48379
+ return { rows, schema, metadata: {} };
47284
48380
  }
47285
- throw Flags.invalidFlagValueError(name);
47286
- });
47287
- }
47288
- static string(name, defaultValue = "") {
47289
- return new SingleValueFlag(name, defaultValue, (stringValue) => stringValue);
47290
- }
47291
- static number(name, defaultValue = 0) {
47292
- return new SingleValueFlag(name, defaultValue, (stringValue) => parseFloat(stringValue));
47293
- }
47294
- static long(name, defaultValue = Long__default["default"].ZERO) {
47295
- return new SingleValueFlag(name, defaultValue, Long__default["default"].fromString);
47296
- }
47297
- static stringSet(name, defaultValue = new Set()) {
47298
- return new SetFlag(name, defaultValue, (singleValue) => singleValue);
48381
+ })
48382
+ .promise();
47299
48383
  }
47300
- static getRawFlagValue(flagName) {
47301
- return Flags.parsedArgv[flagName];
48384
+ async withClientLock(callback) {
48385
+ return await callback(this);
47302
48386
  }
47303
- static setRawFlagValueForTesting(flagName, value) {
47304
- Flags.parsedArgv[flagName] = value;
48387
+ async evaluate(queryOrAction) {
48388
+ const validationQueries = collectEvaluationQueries(queryOrAction, true);
48389
+ return await Promise.all(validationQueries.map(async ({ query, incremental }) => {
48390
+ try {
48391
+ await this.pool
48392
+ .addSingleTask({
48393
+ generator: () => this.getClient().query({
48394
+ useLegacySql: false,
48395
+ query,
48396
+ dryRun: true
48397
+ })
48398
+ })
48399
+ .promise();
48400
+ return sqlanvil.QueryEvaluation.create({
48401
+ status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS,
48402
+ incremental,
48403
+ query
48404
+ });
48405
+ }
48406
+ catch (e) {
48407
+ return {
48408
+ status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
48409
+ error: parseBigqueryEvalError(e),
48410
+ incremental,
48411
+ query
48412
+ };
48413
+ }
48414
+ }));
47305
48415
  }
47306
- static invalidFlagValueError(flagName) {
47307
- return new Error(`Invalid flag value: ${Flags.getRawFlagValue(flagName)} [${flagName}]`);
48416
+ async tables(database, schema) {
48417
+ const datasetIds = schema ? [schema] : await this.schemas(database);
48418
+ const tablesMetadata = [];
48419
+ await Promise.all(datasetIds.map(async (datasetId) => {
48420
+ const [tables] = await this.getClient(database)
48421
+ .dataset(datasetId)
48422
+ .getTables();
48423
+ await Promise.all(tables.map(async (table) => {
48424
+ const metadata = await this.table({
48425
+ database,
48426
+ schema: datasetId,
48427
+ name: table.id
48428
+ });
48429
+ if (metadata) {
48430
+ tablesMetadata.push(metadata);
48431
+ }
48432
+ }));
48433
+ }));
48434
+ return tablesMetadata;
47308
48435
  }
47309
- }
47310
- Flags.parsedArgv = parseArgvFlags(process.argv);
47311
- class AbstractFlag {
47312
- constructor(name, defaultValue) {
47313
- this.name = name;
47314
- this.defaultValue = defaultValue;
47315
- this.parsed = {};
48436
+ async search(searchText, options = { limit: 1000 }) {
48437
+ const results = await this.execute(`select table_catalog, table_schema, table_name
48438
+ from region-${this.bigQueryCredentials.location}.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS
48439
+ where regexp_contains(table_schema, @searchText) or regexp_contains(table_name, @searchText) or regexp_contains(field_path, @searchText)
48440
+ group by 1, 2, 3`, {
48441
+ params: {
48442
+ searchText: `(?i)${searchText}`
48443
+ },
48444
+ interactive: true,
48445
+ rowLimit: options.limit
48446
+ });
48447
+ return await Promise.all(results.rows.map(row => this.table({
48448
+ database: row.table_catalog,
48449
+ schema: row.table_schema,
48450
+ name: row.table_name
48451
+ })));
47316
48452
  }
47317
- get() {
47318
- if (Flags.getRawFlagValue(this.name) === undefined) {
47319
- return this.defaultValue;
48453
+ async table(target) {
48454
+ var _a;
48455
+ const metadata = await this.getMetadata(target);
48456
+ if (!metadata) {
48457
+ return null;
47320
48458
  }
47321
- const stringValue = Flags.getRawFlagValue(this.name);
47322
- if (!(stringValue in this.parsed)) {
47323
- this.parsed[stringValue] = this.parse(stringValue);
48459
+ if (metadata.tableReference.datasetId !== target.schema ||
48460
+ metadata.tableReference.tableId !== target.name) {
48461
+ const metadataTarget = {
48462
+ database: metadata.tableReference.projectId,
48463
+ schema: metadata.tableReference.datasetId,
48464
+ name: metadata.tableReference.tableId
48465
+ };
48466
+ throw new Error(`Target ${JSON.stringify(metadataTarget)} does not match requested target ${JSON.stringify(target)}.`);
47324
48467
  }
47325
- return this.parsed[stringValue];
48468
+ return sqlanvil.TableMetadata.create({
48469
+ type: metadata.type === "TABLE"
48470
+ ? sqlanvil.TableMetadata.Type.TABLE
48471
+ : metadata.type === "VIEW"
48472
+ ? sqlanvil.TableMetadata.Type.VIEW
48473
+ : sqlanvil.TableMetadata.Type.UNKNOWN,
48474
+ target,
48475
+ fields: (_a = metadata.schema.fields) === null || _a === void 0 ? void 0 : _a.map(field => convertField(field)),
48476
+ lastUpdatedMillis: Long__default["default"].fromString(metadata.lastModifiedTime),
48477
+ description: metadata.description,
48478
+ labels: metadata.labels,
48479
+ bigquery: {
48480
+ hasStreamingBuffer: !!metadata.streamingBuffer
48481
+ }
48482
+ });
47326
48483
  }
47327
- }
47328
- class SingleValueFlag extends AbstractFlag {
47329
- constructor(name, defaultValue, parser) {
47330
- super(name, defaultValue);
47331
- this.parser = parser;
48484
+ async deleteTable(target) {
48485
+ await this.getClient(target.database)
48486
+ .dataset(target.schema)
48487
+ .table(target.name)
48488
+ .delete({ ignoreNotFound: true });
47332
48489
  }
47333
- parse(stringValue) {
47334
- return this.parser(stringValue);
48490
+ async schemas(database) {
48491
+ const data = await this.getClient(database).getDatasets();
48492
+ return data[0].map(dataset => dataset.id);
47335
48493
  }
47336
- }
47337
- class SetFlag extends AbstractFlag {
47338
- constructor(name, defaultValue, parser) {
47339
- super(name, defaultValue);
47340
- this.parser = parser;
48494
+ async createSchema(database, schema) {
48495
+ await this.execute(`create schema if not exists \`${database || this.bigQueryCredentials.projectId}.${schema}\``, { bigquery: { location: this.bigQueryCredentials.location } });
47341
48496
  }
47342
- parse(stringValue) {
47343
- return new Set(stringValue
47344
- .split(",")
47345
- .filter(singleValue => singleValue.length > 0)
47346
- .map(this.parser));
48497
+ async setMetadata(action) {
48498
+ const { target, actionDescriptor } = action;
48499
+ const metadata = await this.getMetadata(target);
48500
+ const schemaWithDescription = addDescriptionToMetadata(actionDescriptor.columns, metadata.schema.fields);
48501
+ await this.getClient(target.database)
48502
+ .dataset(target.schema)
48503
+ .table(target.name)
48504
+ .setMetadata({
48505
+ description: actionDescriptor.description,
48506
+ schema: schemaWithDescription,
48507
+ labels: actionDescriptor.bigqueryLabels
48508
+ });
47347
48509
  }
47348
- }
47349
-
47350
- async function retry(fn, maxAttempts = 1, matchesRetriableError = () => true) {
47351
- let lastErr;
47352
- for (let i = 0; i < maxAttempts; i++) {
48510
+ async getMetadata(target) {
48511
+ var _a, _b;
47353
48512
  try {
47354
- return await fn();
48513
+ const table = await this.getClient(target.database)
48514
+ .dataset(target.schema)
48515
+ .table(target.name)
48516
+ .getMetadata();
48517
+ return table === null || table === void 0 ? void 0 : table[0];
47355
48518
  }
47356
48519
  catch (e) {
47357
- if (!matchesRetriableError(e)) {
47358
- throw e;
48520
+ if (((_b = (_a = e === null || e === void 0 ? void 0 : e.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.reason) === "notFound") {
48521
+ return null;
47359
48522
  }
47360
- lastErr = e;
48523
+ throw coerceAsError(e);
47361
48524
  }
47362
48525
  }
47363
- throw lastErr;
47364
- }
47365
-
47366
- const CANCEL_EVENT = "jobCancel";
47367
- const flags = {
47368
- runnerNotificationPeriodMillis: Flags.number("runner-notification-period-millis", 5000)
47369
- };
47370
- const isSuccessfulAction = (actionResult) => actionResult.status === sqlanvil.ActionResult.ExecutionStatus.SUCCESSFUL ||
47371
- actionResult.status === sqlanvil.ActionResult.ExecutionStatus.DISABLED;
47372
- function run(dbadapter, graph, executionOptions, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
47373
- return new Runner(dbadapter, graph, executionOptions, partiallyExecutedRunResult, runnerNotificationPeriodMillis).execute();
47374
- }
47375
- class Runner {
47376
- constructor(dbadapter, graph, executionOptions = {}, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
48526
+ getClient(projectId) {
48527
+ if (this.bigqueryClient) {
48528
+ return this.bigqueryClient;
48529
+ }
48530
+ projectId = projectId || this.bigQueryCredentials.projectId;
48531
+ if (!this.clients.has(projectId)) {
48532
+ this.clients.set(projectId, new bigquery.BigQuery(bigQueryClientOptions(this.bigQueryCredentials, projectId)));
48533
+ }
48534
+ return this.clients.get(projectId);
48535
+ }
48536
+ async runQuery(query, params, rowLimit, byteLimit, location) {
48537
+ const results = await new Promise((resolve, reject) => {
48538
+ const allRows = new LimitedResultSet({
48539
+ rowLimit,
48540
+ byteLimit
48541
+ });
48542
+ const stream = this.getClient().createQueryStream({
48543
+ query,
48544
+ params,
48545
+ location
48546
+ });
48547
+ stream
48548
+ .on("error", e => reject(coerceAsError(e)))
48549
+ .on("data", row => {
48550
+ if (!allRows.push(row)) {
48551
+ stream.end();
48552
+ }
48553
+ })
48554
+ .on("end", () => {
48555
+ resolve(allRows.rows);
48556
+ });
48557
+ });
48558
+ return { rows: cleanRows(results), metadata: {} };
48559
+ }
48560
+ prepareQueryOptions(query, rowLimit, bigqueryOptions, params) {
48561
+ return {
48562
+ query,
48563
+ useLegacySql: false,
48564
+ jobPrefix: "sqlanvil-" + ((bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.jobPrefix) ? `${bigqueryOptions.jobPrefix}-` : ""),
48565
+ location: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.location,
48566
+ maxResults: rowLimit,
48567
+ labels: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.labels,
48568
+ dryRun: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.dryRun,
48569
+ reservation: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.reservation,
48570
+ params
48571
+ };
48572
+ }
48573
+ async createQueryJob(query, params, rowLimit, byteLimit, onCancel, labels, location, jobPrefix, dryRun, reservation) {
48574
+ let isCancelled = false;
48575
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => (isCancelled = true));
48576
+ return retry(async () => {
48577
+ try {
48578
+ const job = await this.getClient().createQueryJob(this.prepareQueryOptions(query, rowLimit, {
48579
+ labels,
48580
+ location,
48581
+ jobPrefix,
48582
+ dryRun,
48583
+ reservation
48584
+ }, params));
48585
+ const resultStream = job[0].getQueryResultsStream();
48586
+ return new Promise((resolve, reject) => {
48587
+ if (isCancelled) {
48588
+ resultStream.end();
48589
+ reject(new Error("Query cancelled."));
48590
+ return;
48591
+ }
48592
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => {
48593
+ resultStream.end();
48594
+ reject(new Error("Query cancelled."));
48595
+ });
48596
+ const results = new LimitedResultSet({
48597
+ rowLimit,
48598
+ byteLimit
48599
+ });
48600
+ resultStream
48601
+ .on("error", async (e) => {
48602
+ var _a, _b;
48603
+ if (dryRun && ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Not found: Job"))) {
48604
+ resolve({ rows: [], metadata: {} });
48605
+ return;
48606
+ }
48607
+ try {
48608
+ const [jobMetadata] = await job[0].getMetadata();
48609
+ if (!!((_b = jobMetadata.status) === null || _b === void 0 ? void 0 : _b.errorResult)) {
48610
+ const error = createBigQueryError(jobMetadata);
48611
+ reject(error);
48612
+ }
48613
+ }
48614
+ catch (metadataError) {
48615
+ reject(metadataError);
48616
+ }
48617
+ reject(e);
48618
+ })
48619
+ .on("data", row => {
48620
+ if (!results.push(row)) {
48621
+ resultStream.end();
48622
+ }
48623
+ })
48624
+ .on("end", async () => {
48625
+ var _a;
48626
+ try {
48627
+ const [jobMetadata] = await job[0].getMetadata();
48628
+ if (!!((_a = jobMetadata.status) === null || _a === void 0 ? void 0 : _a.errorResult)) {
48629
+ const error = createBigQueryError(jobMetadata);
48630
+ reject(error);
48631
+ return;
48632
+ }
48633
+ resolve({
48634
+ rows: results.rows,
48635
+ metadata: {
48636
+ bigquery: {
48637
+ jobId: jobMetadata.jobReference.jobId,
48638
+ totalBytesBilled: jobMetadata.statistics.query.totalBytesBilled
48639
+ ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesBilled)
48640
+ : Long__default["default"].ZERO,
48641
+ totalBytesProcessed: jobMetadata.statistics.query.totalBytesProcessed
48642
+ ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesProcessed)
48643
+ : Long__default["default"].ZERO,
48644
+ }
48645
+ }
48646
+ });
48647
+ }
48648
+ catch (e) {
48649
+ reject(e);
48650
+ }
48651
+ });
48652
+ });
48653
+ }
48654
+ catch (e) {
48655
+ throw coerceAsError(e);
48656
+ }
48657
+ }, BIGQUERY_INTERNAL_ERROR_JOB_MAX_ATTEMPTS, e => { var _a; return (_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Retrying the job may solve the problem"); });
48658
+ }
48659
+ }
48660
+ function cleanRows(rows) {
48661
+ if (rows.length === 0) {
48662
+ return rows;
48663
+ }
48664
+ const sampleData = rows[0];
48665
+ const fieldsWithBigQueryDates = Object.keys(sampleData).filter(key => sampleData[key] &&
48666
+ sampleData[key].constructor &&
48667
+ BIGQUERY_DATE_RELATED_FIELDS.includes(sampleData[key].constructor.name));
48668
+ fieldsWithBigQueryDates.forEach(dateField => {
48669
+ rows.forEach(row => (row[dateField] = row[dateField] ? row[dateField].value : row[dateField]));
48670
+ });
48671
+ return rows;
48672
+ }
48673
+ function convertField(field) {
48674
+ const result = {
48675
+ name: field.name,
48676
+ flags: field.mode === "REPEATED" ? [sqlanvil.Field.Flag.REPEATED] : [],
48677
+ description: field.description
48678
+ };
48679
+ if (field.type === "RECORD" || field.type === "STRUCT") {
48680
+ result.struct = sqlanvil.Fields.create({
48681
+ fields: field.fields.map(innerField => convertField(innerField))
48682
+ });
48683
+ }
48684
+ else {
48685
+ result.primitive = convertFieldType$2(field.type);
48686
+ }
48687
+ return sqlanvil.Field.create(result);
48688
+ }
48689
+ function convertFieldType$2(type) {
48690
+ switch (String(type).toUpperCase()) {
48691
+ case "FLOAT":
48692
+ case "FLOAT64":
48693
+ return sqlanvil.Field.Primitive.FLOAT;
48694
+ case "INTEGER":
48695
+ case "INT64":
48696
+ return sqlanvil.Field.Primitive.INTEGER;
48697
+ case "NUMERIC":
48698
+ return sqlanvil.Field.Primitive.NUMERIC;
48699
+ case "BOOL":
48700
+ case "BOOLEAN":
48701
+ return sqlanvil.Field.Primitive.BOOLEAN;
48702
+ case "STRING":
48703
+ return sqlanvil.Field.Primitive.STRING;
48704
+ case "DATE":
48705
+ return sqlanvil.Field.Primitive.DATE;
48706
+ case "DATETIME":
48707
+ return sqlanvil.Field.Primitive.DATETIME;
48708
+ case "TIMESTAMP":
48709
+ return sqlanvil.Field.Primitive.TIMESTAMP;
48710
+ case "TIME":
48711
+ return sqlanvil.Field.Primitive.TIME;
48712
+ case "BYTES":
48713
+ return sqlanvil.Field.Primitive.BYTES;
48714
+ case "GEOGRAPHY":
48715
+ return sqlanvil.Field.Primitive.GEOGRAPHY;
48716
+ case "BIGNUMERIC":
48717
+ return sqlanvil.Field.Primitive.BIGNUMERIC;
48718
+ case "JSON":
48719
+ return sqlanvil.Field.Primitive.JSON;
48720
+ case "INTERVAL":
48721
+ return sqlanvil.Field.Primitive.INTERVAL;
48722
+ default:
48723
+ return sqlanvil.Field.Primitive.UNKNOWN;
48724
+ }
48725
+ }
48726
+ function addDescriptionToMetadata(columnDescriptions, metadataArray) {
48727
+ if (!columnDescriptions) {
48728
+ return metadataArray;
48729
+ }
48730
+ const findDescription = (path) => columnDescriptions.find(column => column.path.join("") === path.join(""));
48731
+ const mapDescriptionToMetadata = (metadata, path) => {
48732
+ var _a;
48733
+ const description = findDescription(path);
48734
+ if (description) {
48735
+ metadata.description = description.description;
48736
+ if (((_a = description.bigqueryPolicyTags) === null || _a === void 0 ? void 0 : _a.length) > 0) {
48737
+ metadata.policyTags = {
48738
+ names: description.bigqueryPolicyTags
48739
+ };
48740
+ }
48741
+ }
48742
+ if (metadata.fields) {
48743
+ metadata.fields = metadata.fields.map(nestedMetadata => mapDescriptionToMetadata(nestedMetadata, [...path, nestedMetadata.name]));
48744
+ }
48745
+ return metadata;
48746
+ };
48747
+ const newMetadata = metadataArray.map(metaItem => mapDescriptionToMetadata(metaItem, [metaItem.name]));
48748
+ return newMetadata;
48749
+ }
48750
+ function createBigQueryError(jobMetadata) {
48751
+ const error = new Error(jobMetadata.status.errorResult.message);
48752
+ if (jobMetadata.jobReference && jobMetadata.jobReference.jobId) {
48753
+ error.metadata = {
48754
+ bigquery: {
48755
+ jobId: jobMetadata.jobReference.jobId,
48756
+ }
48757
+ };
48758
+ }
48759
+ return error;
48760
+ }
48761
+
48762
+ const maybeInitializePg = (() => {
48763
+ let initialized = false;
48764
+ return () => {
48765
+ if (!initialized) {
48766
+ initialized = true;
48767
+ pg__namespace.types.setTypeParser(20, Number);
48768
+ }
48769
+ };
48770
+ })();
48771
+ class PgPoolExecutor {
48772
+ constructor(clientConfig, options) {
48773
+ maybeInitializePg();
48774
+ this.pool = new pg__namespace.Pool(Object.assign(Object.assign({}, clientConfig), { max: options === null || options === void 0 ? void 0 : options.concurrencyLimit }));
48775
+ this.pool.on("error", err => {
48776
+ console.error("pg.Pool idle client error", err.message, err.stack);
48777
+ });
48778
+ }
48779
+ async verifyConnection() {
48780
+ const client = await this.pool.connect();
48781
+ try {
48782
+ await client.query("select 1");
48783
+ }
48784
+ finally {
48785
+ client.release();
48786
+ }
48787
+ }
48788
+ async withClientLock(callback) {
48789
+ const client = await this.pool.connect();
48790
+ let released = false;
48791
+ const releaseOnce = (err) => {
48792
+ if (released) {
48793
+ return;
48794
+ }
48795
+ released = true;
48796
+ try {
48797
+ client.release(err);
48798
+ }
48799
+ catch (e) {
48800
+ console.error("Error thrown when releasing pg.Client", e.message, e.stack);
48801
+ }
48802
+ };
48803
+ try {
48804
+ client.on("error", err => {
48805
+ console.error("pg.Client client error", err.message, err.stack);
48806
+ releaseOnce(err);
48807
+ });
48808
+ return await callback({
48809
+ execute: async (statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
48810
+ return await new Promise((resolve, reject) => {
48811
+ var _a;
48812
+ const query = client.query(new QueryStream__default["default"](statement, options === null || options === void 0 ? void 0 : options.params));
48813
+ const results = new LimitedResultSet({
48814
+ rowLimit: options === null || options === void 0 ? void 0 : options.rowLimit,
48815
+ byteLimit: options === null || options === void 0 ? void 0 : options.byteLimit
48816
+ });
48817
+ (_a = options === null || options === void 0 ? void 0 : options.onCancel) === null || _a === void 0 ? void 0 : _a.call(options, () => query.destroy(new Error("Query cancelled.")));
48818
+ query.on("data", (row) => {
48819
+ try {
48820
+ verifyUniqueColumnNames(query.cursor._result.fields);
48821
+ }
48822
+ catch (e) {
48823
+ query.destroy(e);
48824
+ return;
48825
+ }
48826
+ if (!results.push(row)) {
48827
+ query.cursor.close();
48828
+ }
48829
+ });
48830
+ query.on("error", err => {
48831
+ releaseOnce(err);
48832
+ reject(err);
48833
+ });
48834
+ query.on("end", () => {
48835
+ resolve(results.rows);
48836
+ });
48837
+ });
48838
+ }
48839
+ });
48840
+ }
48841
+ finally {
48842
+ releaseOnce();
48843
+ }
48844
+ }
48845
+ async close() {
48846
+ await this.pool.end();
48847
+ }
48848
+ }
48849
+ function verifyUniqueColumnNames(fields) {
48850
+ const colNames = new Set();
48851
+ fields.forEach(field => {
48852
+ if (colNames.has(field.name)) {
48853
+ throw new Error(`Ambiguous column name: ${field.name}`);
48854
+ }
48855
+ colNames.add(field.name);
48856
+ });
48857
+ }
48858
+ function convertFieldType$1(type) {
48859
+ switch (String(type).toUpperCase()) {
48860
+ case "FLOAT":
48861
+ case "FLOAT4":
48862
+ case "FLOAT8":
48863
+ case "DOUBLE PRECISION":
48864
+ case "REAL":
48865
+ return sqlanvil.Field.Primitive.FLOAT;
48866
+ case "INTEGER":
48867
+ case "INT":
48868
+ case "INT2":
48869
+ case "INT4":
48870
+ case "INT8":
48871
+ case "BIGINT":
48872
+ case "SMALLINT":
48873
+ return sqlanvil.Field.Primitive.INTEGER;
48874
+ case "DECIMAL":
48875
+ case "NUMERIC":
48876
+ return sqlanvil.Field.Primitive.NUMERIC;
48877
+ case "BOOLEAN":
48878
+ case "BOOL":
48879
+ return sqlanvil.Field.Primitive.BOOLEAN;
48880
+ case "STRING":
48881
+ case "VARCHAR":
48882
+ case "CHAR":
48883
+ case "CHARACTER":
48884
+ case "CHARACTER VARYING":
48885
+ case "NVARCHAR":
48886
+ case "TEXT":
48887
+ case "NCHAR":
48888
+ case "BPCHAR":
48889
+ return sqlanvil.Field.Primitive.STRING;
48890
+ case "DATE":
48891
+ return sqlanvil.Field.Primitive.DATE;
48892
+ case "TIMESTAMP":
48893
+ case "TIMESTAMPZ":
48894
+ case "TIMESTAMP WITHOUT TIME ZONE":
48895
+ case "TIMESTAMP WITH TIME ZONE":
48896
+ return sqlanvil.Field.Primitive.TIMESTAMP;
48897
+ default:
48898
+ return sqlanvil.Field.Primitive.UNKNOWN;
48899
+ }
48900
+ }
48901
+
48902
+ const INTERNAL_SCHEMAS$1 = new Set(["information_schema", "pg_catalog", "pg_internal", "pg_toast"]);
48903
+ class PostgresDbAdapter {
48904
+ constructor(queryExecutor) {
48905
+ this.queryExecutor = queryExecutor;
48906
+ }
48907
+ static async create(credentials, options) {
48908
+ const sslMode = (credentials.sslMode || "").toLowerCase();
48909
+ const sslEnabled = !(options === null || options === void 0 ? void 0 : options.disableSslForTestsOnly) && sslMode !== "disable";
48910
+ const clientConfig = {
48911
+ host: credentials.host,
48912
+ port: credentials.port,
48913
+ database: credentials.database,
48914
+ user: credentials.user,
48915
+ password: credentials.password,
48916
+ ssl: sslEnabled
48917
+ ? {
48918
+ rejectUnauthorized: sslMode === "verify-ca" || sslMode === "verify-full"
48919
+ }
48920
+ : false
48921
+ };
48922
+ const queryExecutor = new PgPoolExecutor(clientConfig, options);
48923
+ try {
48924
+ await queryExecutor.verifyConnection();
48925
+ }
48926
+ catch (e) {
48927
+ await queryExecutor.close().catch(() => undefined);
48928
+ throw new ErrorWithCause(`Could not connect to Postgres at ${credentials.host}:${credentials.port} ` +
48929
+ `as "${credentials.user}": ${e.message}`, e);
48930
+ }
48931
+ return new PostgresDbAdapter(queryExecutor);
48932
+ }
48933
+ async execute(statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) {
48934
+ return await this.withClientLock(client => client.execute(statement, options));
48935
+ }
48936
+ async executeRaw(statement, options = { rowLimit: 1000 }) {
48937
+ const result = await this.execute(statement, options);
48938
+ return Object.assign(Object.assign({}, result), { schema: [] });
48939
+ }
48940
+ async withClientLock(callback) {
48941
+ return await this.queryExecutor.withClientLock(client => callback({
48942
+ execute: async (stmt, opts = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
48943
+ try {
48944
+ const rows = await client.execute(stmt, opts);
48945
+ return { rows, metadata: {} };
48946
+ }
48947
+ catch (e) {
48948
+ if (opts.includeQueryInError) {
48949
+ throw new Error(`Error encountered while running "${stmt}": ${e.message}`);
48950
+ }
48951
+ throw new ErrorWithCause(`Error executing postgres query: ${e.message}`, e);
48952
+ }
48953
+ },
48954
+ executeRaw: async (stmt, opts = { rowLimit: 1000 }) => {
48955
+ const positional = opts.params ? Object.values(opts.params) : undefined;
48956
+ const rows = await client.execute(stmt, { params: positional, rowLimit: opts.rowLimit });
48957
+ return { rows, schema: [], metadata: {} };
48958
+ }
48959
+ }));
48960
+ }
48961
+ async evaluate(queryOrAction) {
48962
+ const validationQueries = collectEvaluationQueries(queryOrAction, false, (query) => !!query ? `explain ${query}` : "").map((validationQuery, index) => ({ index, validationQuery }));
48963
+ const validationQueriesWithoutWrappers = collectEvaluationQueries(queryOrAction, false);
48964
+ const queryEvaluations = new Array();
48965
+ for (const { index, validationQuery } of validationQueries) {
48966
+ let evaluationResponse = {
48967
+ status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS
48968
+ };
48969
+ try {
48970
+ await this.execute(validationQuery.query);
48971
+ }
48972
+ catch (e) {
48973
+ evaluationResponse = {
48974
+ status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
48975
+ error: parsePostgresEvalError(validationQuery.query, e)
48976
+ };
48977
+ }
48978
+ queryEvaluations.push(sqlanvil.QueryEvaluation.create(Object.assign(Object.assign({}, evaluationResponse), { incremental: validationQuery.incremental, query: validationQueriesWithoutWrappers[index].query })));
48979
+ }
48980
+ return queryEvaluations;
48981
+ }
48982
+ async tables(_database, schema) {
48983
+ const params = [];
48984
+ let schemaClause = "";
48985
+ let matviewSchemaClause = "";
48986
+ if (schema) {
48987
+ schemaClause = "and table_schema = $1";
48988
+ matviewSchemaClause = "and schemaname = $1";
48989
+ params.push(schema);
48990
+ }
48991
+ const queryResult = await this.execute(`select table_name, table_schema
48992
+ from information_schema.tables
48993
+ where table_schema not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
48994
+ ${schemaClause}
48995
+ union
48996
+ select matviewname as table_name, schemaname as table_schema
48997
+ from pg_matviews
48998
+ where schemaname not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
48999
+ ${matviewSchemaClause}`, { params, rowLimit: 10000, includeQueryInError: true });
49000
+ const targets = queryResult.rows.map(row => ({
49001
+ schema: row.table_schema,
49002
+ name: row.table_name
49003
+ }));
49004
+ return await Promise.all(targets.map(target => this.table(target)));
49005
+ }
49006
+ async search(searchText, options = { limit: 1000 }) {
49007
+ const results = await this.execute(`select tables.table_schema as table_schema, tables.table_name as table_name
49008
+ from information_schema.tables as tables
49009
+ left join information_schema.columns columns
49010
+ on tables.table_schema = columns.table_schema
49011
+ and tables.table_name = columns.table_name
49012
+ where tables.table_schema ilike $1
49013
+ or tables.table_name ilike $1
49014
+ or columns.column_name ilike $1
49015
+ group by 1, 2`, {
49016
+ params: [`%${searchText}%`],
49017
+ rowLimit: options.limit
49018
+ });
49019
+ return await Promise.all(results.rows.map(row => this.table({
49020
+ schema: row.table_schema,
49021
+ name: row.table_name
49022
+ })));
49023
+ }
49024
+ async table(target) {
49025
+ const params = [target.schema, target.name];
49026
+ const [tableResults, columnResults, descriptionResults, matviewResults, matviewColumns] = await Promise.all([
49027
+ this.execute(`select table_type from information_schema.tables where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49028
+ this.execute(`select column_name, data_type, is_nullable, ordinal_position
49029
+ from information_schema.columns
49030
+ where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49031
+ this.execute(`select objsubid as column_number, description
49032
+ from pg_description
49033
+ where objoid = (
49034
+ select oid from pg_class where relname = $2 and relnamespace = (
49035
+ select oid from pg_namespace where nspname = $1
49036
+ )
49037
+ )`, { params, includeQueryInError: true }),
49038
+ this.execute(`select 1 from pg_matviews where schemaname = $1 and matviewname = $2`, { params, includeQueryInError: true }),
49039
+ this.execute(`select a.attname as column_name, format_type(a.atttypid, a.atttypmod) as data_type,
49040
+ a.attnum as ordinal_position
49041
+ from pg_attribute a
49042
+ join pg_class c on c.oid = a.attrelid
49043
+ join pg_namespace n on n.oid = c.relnamespace
49044
+ where n.nspname = $1 and c.relname = $2 and a.attnum > 0 and not a.attisdropped
49045
+ order by a.attnum`, { params, includeQueryInError: true })
49046
+ ]);
49047
+ const findDescription = (columnNumber) => { var _a; return (_a = descriptionResults.rows.find(row => row.column_number === columnNumber)) === null || _a === void 0 ? void 0 : _a.description; };
49048
+ if (tableResults.rows.length > 0) {
49049
+ return sqlanvil.TableMetadata.create({
49050
+ target,
49051
+ type: tableResults.rows[0].table_type === "VIEW"
49052
+ ? sqlanvil.TableMetadata.Type.VIEW
49053
+ : sqlanvil.TableMetadata.Type.TABLE,
49054
+ fields: columnResults.rows.map(row => sqlanvil.Field.create({
49055
+ name: row.column_name,
49056
+ primitive: convertFieldType$1(row.data_type),
49057
+ description: findDescription(row.ordinal_position)
49058
+ })),
49059
+ description: findDescription(0)
49060
+ });
49061
+ }
49062
+ if (matviewResults.rows.length > 0) {
49063
+ return sqlanvil.TableMetadata.create({
49064
+ target,
49065
+ type: sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW,
49066
+ fields: matviewColumns.rows.map(row => sqlanvil.Field.create({
49067
+ name: row.column_name,
49068
+ primitive: convertFieldType$1(String(row.data_type).replace(/\(.*\)/, "")),
49069
+ description: findDescription(row.ordinal_position)
49070
+ })),
49071
+ description: findDescription(0)
49072
+ });
49073
+ }
49074
+ return null;
49075
+ }
49076
+ async deleteTable(target) {
49077
+ const metadata = await this.table(target);
49078
+ if (!metadata) {
49079
+ return;
49080
+ }
49081
+ const kind = metadata.type === sqlanvil.TableMetadata.Type.VIEW ? "view" : "table";
49082
+ await this.execute(`drop ${kind} if exists "${target.schema}"."${target.name}" cascade`, { includeQueryInError: true });
49083
+ }
49084
+ async schemas(_database) {
49085
+ const result = await this.execute(`select nspname from pg_namespace`, {
49086
+ includeQueryInError: true
49087
+ });
49088
+ return result.rows
49089
+ .map(row => row.nspname)
49090
+ .filter(name => !INTERNAL_SCHEMAS$1.has(name) && !name.startsWith("pg_"));
49091
+ }
49092
+ async createSchema(_database, schema) {
49093
+ await this.execute(`create schema if not exists "${schema}"`, {
49094
+ includeQueryInError: true
49095
+ });
49096
+ }
49097
+ async setMetadata(action) {
49098
+ var _a;
49099
+ const { target, actionDescriptor, tableType } = action;
49100
+ const actualMetadata = await this.table(target);
49101
+ if (!actualMetadata) {
49102
+ return;
49103
+ }
49104
+ const relationKind = actualMetadata.type === sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW
49105
+ ? "materialized view"
49106
+ : tableType === "view"
49107
+ ? "view"
49108
+ : "table";
49109
+ const queries = [];
49110
+ if (actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.description) {
49111
+ queries.push(this.execute(`comment on ${relationKind} "${target.schema}"."${target.name}" is '${actionDescriptor.description.replace(/'/g, "''")}'`));
49112
+ }
49113
+ if (((_a = actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.columns) === null || _a === void 0 ? void 0 : _a.length) > 0) {
49114
+ actionDescriptor.columns
49115
+ .filter(column => column.path.length === 1 &&
49116
+ actualMetadata.fields.some(field => field.name === column.path[0]))
49117
+ .forEach(column => {
49118
+ queries.push(this.execute(`comment on column "${target.schema}"."${target.name}"."${column.path[0]}" is '${column.description.replace(/'/g, "''")}'`));
49119
+ });
49120
+ }
49121
+ await Promise.all(queries);
49122
+ }
49123
+ async close() {
49124
+ await this.queryExecutor.close();
49125
+ }
49126
+ }
49127
+
49128
+ const DEFAULT_ROW_CAP = 1000000;
49129
+ const DEFAULT_BYTE_CAP = 512 * 1024 * 1024;
49130
+ const MAX_PARAMS_PER_INSERT = 60000;
49131
+ const quoteIdent = (id) => `"${String(id).replace(/"/g, '""')}"`;
49132
+ function coerce(v) {
49133
+ if (v === null || v === undefined) {
49134
+ return null;
49135
+ }
49136
+ if (typeof v === "object" && v !== null && "value" in v) {
49137
+ return v.value;
49138
+ }
49139
+ return v;
49140
+ }
49141
+ async function runBigQueryExtract(args) {
49142
+ var _a, _b;
49143
+ const { spec, target, connectionCredentials } = args;
49144
+ if ((spec.platform || "bigquery") !== "bigquery") {
49145
+ throw new Error(`runner-extract supports only bigquery sources (got "${spec.platform}").`);
49146
+ }
49147
+ const cols = Object.keys(spec.columnTypes || {});
49148
+ if (cols.length === 0) {
49149
+ throw new Error(`Extract "${target.schema}.${target.name}" has no columnTypes; run \`sqlanvil introspect\`.`);
49150
+ }
49151
+ if (!args.pg) {
49152
+ throw new Error("runner-extract needs the write-warehouse connection (warehouseConnection).");
49153
+ }
49154
+ const conn = (connectionCredentials === null || connectionCredentials === void 0 ? void 0 : connectionCredentials[spec.connectionName]) || {};
49155
+ const bq = new BigQueryDbAdapter(sqlanvil.BigQuery.create({
49156
+ projectId: spec.billingProject || spec.project,
49157
+ location: conn.location,
49158
+ accessToken: conn.accessToken,
49159
+ credentials: conn.credentials
49160
+ }));
49161
+ const rowCap = (_a = args.rowCap) !== null && _a !== void 0 ? _a : DEFAULT_ROW_CAP;
49162
+ const byteCap = (_b = args.byteCap) !== null && _b !== void 0 ? _b : DEFAULT_BYTE_CAP;
49163
+ const colList = cols.map(c => "`" + c + "`").join(", ");
49164
+ const fqn = "`" + `${spec.project}.${spec.dataset}.${spec.sourceName}` + "`";
49165
+ const { rows } = await bq.execute(`select ${colList} from ${fqn}`, {
49166
+ rowLimit: rowCap,
49167
+ byteLimit: byteCap
49168
+ });
49169
+ if (rows.length >= rowCap) {
49170
+ console.warn(`runner-extract: ${target.schema}.${target.name} truncated at ${rowCap} rows (source is larger).`);
49171
+ }
49172
+ const pg = await PostgresDbAdapter.create(args.pg, {
49173
+ disableSslForTestsOnly: args.disableSslForTestsOnly
49174
+ });
49175
+ try {
49176
+ const qualified = `${quoteIdent(target.schema)}.${quoteIdent(target.name)}`;
49177
+ const colDefs = cols.map(c => `${quoteIdent(c)} ${spec.columnTypes[c]}`).join(", ");
49178
+ await pg.execute(`create schema if not exists ${quoteIdent(target.schema)}`);
49179
+ await pg.execute(`drop foreign table if exists ${qualified} cascade`);
49180
+ await pg.execute(`drop table if exists ${qualified} cascade`);
49181
+ await pg.execute(`create table ${qualified} (${colDefs})`);
49182
+ const colIdents = cols.map(quoteIdent).join(", ");
49183
+ const batchRows = Math.max(1, Math.min(1000, Math.floor(MAX_PARAMS_PER_INSERT / cols.length)));
49184
+ for (let i = 0; i < rows.length; i += batchRows) {
49185
+ const batch = rows.slice(i, i + batchRows);
49186
+ const params = [];
49187
+ const tuples = batch.map((row, r) => {
49188
+ const placeholders = cols.map((c, ci) => `$${r * cols.length + ci + 1}`);
49189
+ cols.forEach(c => params.push(coerce(row[c])));
49190
+ return `(${placeholders.join(", ")})`;
49191
+ });
49192
+ await pg.execute(`insert into ${qualified} (${colIdents}) values ${tuples.join(", ")}`, {
49193
+ params
49194
+ });
49195
+ }
49196
+ return { rowCount: rows.length };
49197
+ }
49198
+ finally {
49199
+ await pg.close();
49200
+ }
49201
+ }
49202
+
49203
+ function loadDuckdb() {
49204
+ try {
49205
+ return nativeRequire("@duckdb/node-api");
49206
+ }
49207
+ catch (e) {
49208
+ throw new Error(`This feature requires the optional "@duckdb/node-api" dependency, which failed to load: ` +
49209
+ `${e.message}`);
49210
+ }
49211
+ }
49212
+ async function runAsync(conn, sql) {
49213
+ await conn.run(sql);
49214
+ }
49215
+ async function allAsync(conn, sql) {
49216
+ const reader = await conn.runAndReadAll(sql);
49217
+ return reader.getRowObjects();
49218
+ }
49219
+ async function withDuckdb(fn, dbPath = ":memory:") {
49220
+ const { DuckDBInstance } = loadDuckdb();
49221
+ const instance = await DuckDBInstance.create(dbPath);
49222
+ const conn = await instance.connect();
49223
+ const done = () => {
49224
+ var _a, _b;
49225
+ try {
49226
+ (_a = conn.closeSync) === null || _a === void 0 ? void 0 : _a.call(conn);
49227
+ }
49228
+ catch (e) {
49229
+ }
49230
+ try {
49231
+ (_b = instance.closeSync) === null || _b === void 0 ? void 0 : _b.call(instance);
49232
+ }
49233
+ catch (e) {
49234
+ }
49235
+ };
49236
+ try {
49237
+ if (!process.env.HOME) {
49238
+ await runAsync(conn, `SET home_directory='${os__namespace.tmpdir()}'`);
49239
+ }
49240
+ const result = await fn(conn);
49241
+ done();
49242
+ return result;
49243
+ }
49244
+ catch (e) {
49245
+ done();
49246
+ throw e;
49247
+ }
49248
+ }
49249
+
49250
+ const PG_ATTACH_ALIAS = "pg";
49251
+ const SECRET_NAME = "sa_export";
49252
+ function buildAttachSql(pg, opts = {}) {
49253
+ const readOnly = opts.readOnly !== false;
49254
+ const dsn = [
49255
+ pg.host && `host=${pg.host}`,
49256
+ pg.port && `port=${pg.port}`,
49257
+ pg.database && `dbname=${pg.database}`,
49258
+ pg.user && `user=${pg.user}`,
49259
+ pg.password && `password=${pg.password}`
49260
+ ]
49261
+ .filter(Boolean)
49262
+ .join(" ");
49263
+ const mode = readOnly ? ", READ_ONLY" : "";
49264
+ return `ATTACH '${dsn}' AS ${PG_ATTACH_ALIAS} (TYPE postgres${mode})`;
49265
+ }
49266
+ function buildSecretSql(scheme, creds) {
49267
+ if (scheme === "s3") {
49268
+ const fields = [
49269
+ "TYPE s3",
49270
+ creds.accessKeyId && `KEY_ID '${creds.accessKeyId}'`,
49271
+ creds.secretAccessKey && `SECRET '${creds.secretAccessKey}'`,
49272
+ creds.region && `REGION '${creds.region}'`,
49273
+ creds.endpoint && `ENDPOINT '${creds.endpoint}'`,
49274
+ creds.endpoint && `URL_STYLE 'path'`,
49275
+ creds.endpoint && `USE_SSL true`
49276
+ ]
49277
+ .filter(Boolean)
49278
+ .join(", ");
49279
+ return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
49280
+ }
49281
+ if (scheme === "gcs") {
49282
+ const fields = [
49283
+ "TYPE gcs",
49284
+ creds.keyId && `KEY_ID '${creds.keyId}'`,
49285
+ creds.secret && `SECRET '${creds.secret}'`
49286
+ ]
49287
+ .filter(Boolean)
49288
+ .join(", ");
49289
+ return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
49290
+ }
49291
+ return null;
49292
+ }
49293
+ function toCopyTarget(uri) {
49294
+ if (uri.startsWith("local://")) {
49295
+ return uri.slice("local://".length);
49296
+ }
49297
+ return uri;
49298
+ }
49299
+ function schemeOf(uri) {
49300
+ if (uri.startsWith("s3://")) {
49301
+ return "s3";
49302
+ }
49303
+ if (uri.startsWith("gs://") || uri.startsWith("gcs://")) {
49304
+ return "gcs";
49305
+ }
49306
+ return "local";
49307
+ }
49308
+ function buildCopySql(selectSql, uri, format, options = {}) {
49309
+ const target = toCopyTarget(uri);
49310
+ const fmt = (format || "").toLowerCase();
49311
+ const extraOptions = Object.entries(options || {}).map(([key, value]) => `${key.toUpperCase()} ${value}`);
49312
+ const optionList = [`FORMAT ${fmt}`, ...extraOptions].join(", ");
49313
+ return `COPY (SELECT * FROM postgres_query('${PG_ATTACH_ALIAS}', $sa$${selectSql}$sa$)) TO '${target}' (${optionList})`;
49314
+ }
49315
+ async function runDuckdbExport(args) {
49316
+ const { spec, selectSql, pg, storage, actionName } = args;
49317
+ const uri = resolveExportUri(spec, actionName, { wildcard: false });
49318
+ const scheme = schemeOf(uri);
49319
+ if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
49320
+ throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
49321
+ `export to ${uri}.`);
49322
+ }
49323
+ return withDuckdb(async (conn) => {
49324
+ await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
49325
+ await runAsync(conn, buildAttachSql(pg));
49326
+ if (scheme !== "local") {
49327
+ const secret = buildSecretSql(scheme, storage[scheme]);
49328
+ if (secret) {
49329
+ await runAsync(conn, secret);
49330
+ }
49331
+ }
49332
+ await runAsync(conn, buildCopySql(selectSql, uri, spec.format, spec.options || {}));
49333
+ return { destination: toCopyTarget(uri) };
49334
+ });
49335
+ }
49336
+
49337
+ function readerForFormat(format) {
49338
+ switch ((format || "").toLowerCase()) {
49339
+ case "csv":
49340
+ return "read_csv_auto";
49341
+ case "json":
49342
+ return "read_json_auto";
49343
+ case "parquet":
49344
+ default:
49345
+ return "read_parquet";
49346
+ }
49347
+ }
49348
+ function importTargetSql(target) {
49349
+ return target.schema
49350
+ ? `${PG_ATTACH_ALIAS}."${target.schema}"."${target.name}"`
49351
+ : `${PG_ATTACH_ALIAS}."${target.name}"`;
49352
+ }
49353
+ function buildImportSql(target, location, format, overwrite) {
49354
+ const reader = readerForFormat(format);
49355
+ const source = toCopyTarget(location);
49356
+ const dest = importTargetSql(target);
49357
+ const select = `SELECT * FROM ${reader}('${source}')`;
49358
+ if (overwrite) {
49359
+ return [`DROP TABLE IF EXISTS ${dest}`, `CREATE TABLE ${dest} AS ${select}`];
49360
+ }
49361
+ return [`INSERT INTO ${dest} ${select}`];
49362
+ }
49363
+ async function runDuckdbImport(args) {
49364
+ const { spec, target, pg, storage } = args;
49365
+ const location = spec.location || "";
49366
+ const scheme = schemeOf(location);
49367
+ if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
49368
+ throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
49369
+ `import from ${location}.`);
49370
+ }
49371
+ return withDuckdb(async (conn) => {
49372
+ await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
49373
+ await runAsync(conn, buildAttachSql(pg, { readOnly: false }));
49374
+ if (scheme !== "local") {
49375
+ const secret = buildSecretSql(scheme, storage[scheme]);
49376
+ if (secret) {
49377
+ await runAsync(conn, secret);
49378
+ }
49379
+ }
49380
+ for (const statement of buildImportSql(target, location, spec.format, spec.overwrite)) {
49381
+ await runAsync(conn, statement);
49382
+ }
49383
+ return { source: toCopyTarget(location) };
49384
+ });
49385
+ }
49386
+
49387
+ function parseArgvFlags(argv) {
49388
+ const parsedArgv = {};
49389
+ const splitArgv = [];
49390
+ for (let arg of argv) {
49391
+ if (arg.startsWith("--no-")) {
49392
+ arg = `--${arg.slice(5)}=false`;
49393
+ }
49394
+ if (arg.startsWith("--") && arg.includes("=")) {
49395
+ splitArgv.push(arg.slice(0, arg.indexOf("=")));
49396
+ splitArgv.push(arg.slice(arg.indexOf("=") + 1));
49397
+ }
49398
+ else {
49399
+ splitArgv.push(arg);
49400
+ }
49401
+ }
49402
+ let currentFlagName = "";
49403
+ for (const splitArg of splitArgv) {
49404
+ if (splitArg.startsWith("--")) {
49405
+ currentFlagName = splitArg.slice(2);
49406
+ parsedArgv[currentFlagName] = "";
49407
+ }
49408
+ else if (currentFlagName) {
49409
+ parsedArgv[currentFlagName] = splitArg;
49410
+ currentFlagName = "";
49411
+ }
49412
+ }
49413
+ return parsedArgv;
49414
+ }
49415
+ class Flags {
49416
+ static boolean(name, defaultValue = false) {
49417
+ return new SingleValueFlag(name, defaultValue, (stringValue) => {
49418
+ if (stringValue === "" || stringValue === "true") {
49419
+ return true;
49420
+ }
49421
+ if (stringValue === "false") {
49422
+ return false;
49423
+ }
49424
+ throw Flags.invalidFlagValueError(name);
49425
+ });
49426
+ }
49427
+ static string(name, defaultValue = "") {
49428
+ return new SingleValueFlag(name, defaultValue, (stringValue) => stringValue);
49429
+ }
49430
+ static number(name, defaultValue = 0) {
49431
+ return new SingleValueFlag(name, defaultValue, (stringValue) => parseFloat(stringValue));
49432
+ }
49433
+ static long(name, defaultValue = Long__default["default"].ZERO) {
49434
+ return new SingleValueFlag(name, defaultValue, Long__default["default"].fromString);
49435
+ }
49436
+ static stringSet(name, defaultValue = new Set()) {
49437
+ return new SetFlag(name, defaultValue, (singleValue) => singleValue);
49438
+ }
49439
+ static getRawFlagValue(flagName) {
49440
+ return Flags.parsedArgv[flagName];
49441
+ }
49442
+ static setRawFlagValueForTesting(flagName, value) {
49443
+ Flags.parsedArgv[flagName] = value;
49444
+ }
49445
+ static invalidFlagValueError(flagName) {
49446
+ return new Error(`Invalid flag value: ${Flags.getRawFlagValue(flagName)} [${flagName}]`);
49447
+ }
49448
+ }
49449
+ Flags.parsedArgv = parseArgvFlags(process.argv);
49450
+ class AbstractFlag {
49451
+ constructor(name, defaultValue) {
49452
+ this.name = name;
49453
+ this.defaultValue = defaultValue;
49454
+ this.parsed = {};
49455
+ }
49456
+ get() {
49457
+ if (Flags.getRawFlagValue(this.name) === undefined) {
49458
+ return this.defaultValue;
49459
+ }
49460
+ const stringValue = Flags.getRawFlagValue(this.name);
49461
+ if (!(stringValue in this.parsed)) {
49462
+ this.parsed[stringValue] = this.parse(stringValue);
49463
+ }
49464
+ return this.parsed[stringValue];
49465
+ }
49466
+ }
49467
+ class SingleValueFlag extends AbstractFlag {
49468
+ constructor(name, defaultValue, parser) {
49469
+ super(name, defaultValue);
49470
+ this.parser = parser;
49471
+ }
49472
+ parse(stringValue) {
49473
+ return this.parser(stringValue);
49474
+ }
49475
+ }
49476
+ class SetFlag extends AbstractFlag {
49477
+ constructor(name, defaultValue, parser) {
49478
+ super(name, defaultValue);
49479
+ this.parser = parser;
49480
+ }
49481
+ parse(stringValue) {
49482
+ return new Set(stringValue
49483
+ .split(",")
49484
+ .filter(singleValue => singleValue.length > 0)
49485
+ .map(this.parser));
49486
+ }
49487
+ }
49488
+
49489
+ const CANCEL_EVENT = "jobCancel";
49490
+ const flags = {
49491
+ runnerNotificationPeriodMillis: Flags.number("runner-notification-period-millis", 5000)
49492
+ };
49493
+ const isSuccessfulAction = (actionResult) => actionResult.status === sqlanvil.ActionResult.ExecutionStatus.SUCCESSFUL ||
49494
+ actionResult.status === sqlanvil.ActionResult.ExecutionStatus.DISABLED;
49495
+ function run(dbadapter, graph, executionOptions, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
49496
+ return new Runner(dbadapter, graph, executionOptions, partiallyExecutedRunResult, runnerNotificationPeriodMillis).execute();
49497
+ }
49498
+ class Runner {
49499
+ constructor(dbadapter, graph, executionOptions = {}, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
47377
49500
  var _a;
47378
49501
  this.dbadapter = dbadapter;
47379
49502
  this.graph = graph;
@@ -47680,6 +49803,24 @@ class Runner {
47680
49803
  taskResult.errorMessage = `${this.graph.projectConfig.warehouse} import error: ${e.message}`;
47681
49804
  }
47682
49805
  }
49806
+ else if (task.type === "extract") {
49807
+ try {
49808
+ const extractor = this.executionOptions.bigQueryExtract || runBigQueryExtract;
49809
+ await extractor({
49810
+ spec: action === null || action === void 0 ? void 0 : action.extract,
49811
+ target: action === null || action === void 0 ? void 0 : action.target,
49812
+ pg: this.executionOptions.warehouseConnection,
49813
+ connectionCredentials: this.executionOptions.connectionCredentials || {}
49814
+ });
49815
+ taskResult.status = sqlanvil.TaskResult.ExecutionStatus.SUCCESSFUL;
49816
+ }
49817
+ catch (e) {
49818
+ taskResult.status = this.cancelled
49819
+ ? sqlanvil.TaskResult.ExecutionStatus.CANCELLED
49820
+ : sqlanvil.TaskResult.ExecutionStatus.FAILED;
49821
+ taskResult.errorMessage = `${this.graph.projectConfig.warehouse} extract error: ${e.message}`;
49822
+ }
49823
+ }
47683
49824
  else {
47684
49825
  try {
47685
49826
  const statement = this.executionOptions.connectionCredentials
@@ -48321,576 +50462,94 @@ async function validate(compiledGraph, deps, options = {}) {
48321
50462
  nodes.push({
48322
50463
  key: targetKey(table.target),
48323
50464
  dependencyKeys: depKeys(table.dependencyTargets),
48324
- kind: "table",
48325
- type: tableType(table.enumType),
48326
- target: table.target,
48327
- table,
48328
- action: table
48329
- });
48330
- }
48331
- for (const assertion of compiledGraph.assertions || []) {
48332
- nodes.push({
48333
- key: targetKey(assertion.target),
48334
- dependencyKeys: depKeys(assertion.dependencyTargets),
48335
- kind: "assertion",
48336
- type: "assertion",
48337
- target: assertion.target,
48338
- action: assertion
48339
- });
48340
- }
48341
- for (const operation of compiledGraph.operations || []) {
48342
- if (!operation.target) {
48343
- continue;
48344
- }
48345
- nodes.push({
48346
- key: targetKey(operation.target),
48347
- dependencyKeys: depKeys(operation.dependencyTargets),
48348
- kind: "operation",
48349
- type: "operation",
48350
- target: operation.target,
48351
- action: undefined
48352
- });
48353
- }
48354
- for (const imp of compiledGraph.imports || []) {
48355
- if (!imp.target) {
48356
- continue;
48357
- }
48358
- nodes.push({
48359
- key: targetKey(imp.target),
48360
- dependencyKeys: depKeys(imp.dependencyTargets),
48361
- kind: "import",
48362
- type: "import",
48363
- target: imp.target,
48364
- action: undefined
48365
- });
48366
- }
48367
- const ordered = topoOrder(nodes);
48368
- const shadowSchemas = Array.from(new Set(nodes.filter(n => n.kind === "table").map(n => n.target.schema)));
48369
- const statusByKey = new Map();
48370
- const results = [];
48371
- try {
48372
- for (const schema of shadowSchemas) {
48373
- await deps.execute(deps.createSchemaSql(schema));
48374
- }
48375
- for (const node of ordered) {
48376
- if (node.kind === "operation" || node.kind === "import") {
48377
- statusByKey.set(node.key, "SKIPPED");
48378
- results.push({ target: node.target, type: node.type, status: "SKIPPED", errors: [] });
48379
- continue;
48380
- }
48381
- if (dependencyBlocked(node.dependencyKeys, statusByKey)) {
48382
- statusByKey.set(node.key, "BLOCKED");
48383
- results.push({ target: node.target, type: node.type, status: "BLOCKED", errors: [] });
48384
- continue;
48385
- }
48386
- const evaluations = await deps.evaluate(node.action);
48387
- const failed = evaluations.some(e => e.status === sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE);
48388
- const status = failed ? "FAILURE" : "PASS";
48389
- statusByKey.set(node.key, status);
48390
- results.push({ target: node.target, type: node.type, status, errors: evaluations });
48391
- if (status === "PASS" && node.kind === "table") {
48392
- try {
48393
- await deps.execute(deps.validationStubSql(node.table));
48394
- }
48395
- catch (e) {
48396
- }
48397
- }
48398
- }
48399
- }
48400
- finally {
48401
- if (!options.keepShadow) {
48402
- for (const schema of shadowSchemas.slice().reverse()) {
48403
- try {
48404
- await deps.execute(deps.dropSchemaCascadeSql(schema));
48405
- }
48406
- catch (e) {
48407
- }
48408
- }
48409
- }
48410
- }
48411
- return results;
48412
- }
48413
-
48414
- function parsePostgresEvalError(_query, error) {
48415
- return sqlanvil.QueryEvaluationError.create({
48416
- message: (error === null || error === void 0 ? void 0 : error.message) ? String(error.message) : String(error)
48417
- });
48418
- }
48419
- function parseBigqueryEvalError(error) {
48420
- const evalError = sqlanvil.QueryEvaluationError.create({
48421
- message: String(error)
48422
- });
48423
- try {
48424
- if (!error.message) {
48425
- return evalError;
48426
- }
48427
- const bracketsString = error.message.split("[").slice(-1)[0];
48428
- const [_, lineNumber, columnNumber] = bracketsString.match(/([0-9]*)[^0-9]*([0-9]*).*/);
48429
- const line = Number(lineNumber);
48430
- const column = Number(columnNumber);
48431
- if (line || line === 0) {
48432
- evalError.errorLocation = { line, column };
48433
- }
48434
- }
48435
- catch (_) {
48436
- }
48437
- return evalError;
48438
- }
48439
-
48440
- class LimitedResultSet {
48441
- constructor(options) {
48442
- this.options = options;
48443
- this.results = [];
48444
- this.currentBytes = 0;
48445
- }
48446
- push(row) {
48447
- var _a, _b, _c, _d;
48448
- this.currentBytes += sizeof__default["default"](row);
48449
- if ((((_a = this.options) === null || _a === void 0 ? void 0 : _a.rowLimit) && this.results.length >= ((_b = this.options) === null || _b === void 0 ? void 0 : _b.rowLimit)) ||
48450
- (((_c = this.options) === null || _c === void 0 ? void 0 : _c.byteLimit) && this.currentBytes >= ((_d = this.options) === null || _d === void 0 ? void 0 : _d.byteLimit))) {
48451
- return false;
48452
- }
48453
- this.results.push(row);
48454
- return true;
48455
- }
48456
- get rows() {
48457
- return this.results;
48458
- }
48459
- }
48460
-
48461
- const EXTRA_GOOGLE_SCOPES = ["https://www.googleapis.com/auth/drive"];
48462
- const BIGQUERY_DATE_RELATED_FIELDS = [
48463
- "BigQueryDate",
48464
- "BigQueryTime",
48465
- "BigQueryTimestamp",
48466
- "BigQueryDatetime"
48467
- ];
48468
- const BIGQUERY_INTERNAL_ERROR_JOB_MAX_ATTEMPTS = 3;
48469
- class BigQueryDbAdapter {
48470
- constructor(credentials, options) {
48471
- this.clients = new Map();
48472
- this.bigQueryCredentials = credentials;
48473
- this.bigqueryClient = options === null || options === void 0 ? void 0 : options.bigqueryClient;
48474
- this.pool = new promisePoolExecutor.PromisePoolExecutor({
48475
- concurrencyLimit: options === null || options === void 0 ? void 0 : options.concurrencyLimit,
48476
- frequencyWindow: 1000,
48477
- frequencyLimit: 30
48478
- });
48479
- }
48480
- async execute(statement, options = { interactive: false, rowLimit: 1000, byteLimit: 1024 * 1024 }) {
48481
- var _a;
48482
- if ((options === null || options === void 0 ? void 0 : options.interactive) && ((_a = options === null || options === void 0 ? void 0 : options.bigquery) === null || _a === void 0 ? void 0 : _a.labels)) {
48483
- throw new Error("BigQuery job labels may not be set for interactive queries.");
48484
- }
48485
- if (!statement) {
48486
- throw new Error("Query string cannot be empty");
48487
- }
48488
- return this.pool
48489
- .addSingleTask({
48490
- generator: () => {
48491
- var _a, _b, _c, _d, _e, _f;
48492
- return (options === null || options === void 0 ? void 0 : options.interactive) ? this.runQuery(statement, options === null || options === void 0 ? void 0 : options.params, options === null || options === void 0 ? void 0 : options.rowLimit, options === null || options === void 0 ? void 0 : options.byteLimit, (_a = options.bigquery) === null || _a === void 0 ? void 0 : _a.location)
48493
- : this.createQueryJob(statement, options === null || options === void 0 ? void 0 : options.params, options === null || options === void 0 ? void 0 : options.rowLimit, options === null || options === void 0 ? void 0 : options.byteLimit, options === null || options === void 0 ? void 0 : options.onCancel, (_b = options === null || options === void 0 ? void 0 : options.bigquery) === null || _b === void 0 ? void 0 : _b.labels, (_c = options === null || options === void 0 ? void 0 : options.bigquery) === null || _c === void 0 ? void 0 : _c.location, (_d = options === null || options === void 0 ? void 0 : options.bigquery) === null || _d === void 0 ? void 0 : _d.jobPrefix, (_e = options === null || options === void 0 ? void 0 : options.bigquery) === null || _e === void 0 ? void 0 : _e.dryRun, (_f = options === null || options === void 0 ? void 0 : options.bigquery) === null || _f === void 0 ? void 0 : _f.reservation);
48494
- }
48495
- })
48496
- .promise();
48497
- }
48498
- async executeRaw(statement, options = { rowLimit: 1000 }) {
48499
- if (!statement) {
48500
- throw new Error("Query string cannot be empty");
48501
- }
48502
- return this.pool
48503
- .addSingleTask({
48504
- generator: async () => {
48505
- var _a, _b;
48506
- const [rows, , apiResponse] = await this.getClient().query(Object.assign(Object.assign({}, this.prepareQueryOptions(statement, options.rowLimit, options.bigquery, options.params)), { skipParsing: true }));
48507
- const schema = (_b = (_a = apiResponse === null || apiResponse === void 0 ? void 0 : apiResponse.schema) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b.map((field) => convertField(field));
48508
- return { rows, schema, metadata: {} };
48509
- }
48510
- })
48511
- .promise();
48512
- }
48513
- async withClientLock(callback) {
48514
- return await callback(this);
48515
- }
48516
- async evaluate(queryOrAction) {
48517
- const validationQueries = collectEvaluationQueries(queryOrAction, true);
48518
- return await Promise.all(validationQueries.map(async ({ query, incremental }) => {
48519
- try {
48520
- await this.pool
48521
- .addSingleTask({
48522
- generator: () => this.getClient().query({
48523
- useLegacySql: false,
48524
- query,
48525
- dryRun: true
48526
- })
48527
- })
48528
- .promise();
48529
- return sqlanvil.QueryEvaluation.create({
48530
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS,
48531
- incremental,
48532
- query
48533
- });
48534
- }
48535
- catch (e) {
48536
- return {
48537
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
48538
- error: parseBigqueryEvalError(e),
48539
- incremental,
48540
- query
48541
- };
48542
- }
48543
- }));
48544
- }
48545
- async tables(database, schema) {
48546
- const datasetIds = schema ? [schema] : await this.schemas(database);
48547
- const tablesMetadata = [];
48548
- await Promise.all(datasetIds.map(async (datasetId) => {
48549
- const [tables] = await this.getClient(database)
48550
- .dataset(datasetId)
48551
- .getTables();
48552
- await Promise.all(tables.map(async (table) => {
48553
- const metadata = await this.table({
48554
- database,
48555
- schema: datasetId,
48556
- name: table.id
48557
- });
48558
- if (metadata) {
48559
- tablesMetadata.push(metadata);
48560
- }
48561
- }));
48562
- }));
48563
- return tablesMetadata;
48564
- }
48565
- async search(searchText, options = { limit: 1000 }) {
48566
- const results = await this.execute(`select table_catalog, table_schema, table_name
48567
- from region-${this.bigQueryCredentials.location}.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS
48568
- where regexp_contains(table_schema, @searchText) or regexp_contains(table_name, @searchText) or regexp_contains(field_path, @searchText)
48569
- group by 1, 2, 3`, {
48570
- params: {
48571
- searchText: `(?i)${searchText}`
48572
- },
48573
- interactive: true,
48574
- rowLimit: options.limit
48575
- });
48576
- return await Promise.all(results.rows.map(row => this.table({
48577
- database: row.table_catalog,
48578
- schema: row.table_schema,
48579
- name: row.table_name
48580
- })));
48581
- }
48582
- async table(target) {
48583
- var _a;
48584
- const metadata = await this.getMetadata(target);
48585
- if (!metadata) {
48586
- return null;
48587
- }
48588
- if (metadata.tableReference.datasetId !== target.schema ||
48589
- metadata.tableReference.tableId !== target.name) {
48590
- const metadataTarget = {
48591
- database: metadata.tableReference.projectId,
48592
- schema: metadata.tableReference.datasetId,
48593
- name: metadata.tableReference.tableId
48594
- };
48595
- throw new Error(`Target ${JSON.stringify(metadataTarget)} does not match requested target ${JSON.stringify(target)}.`);
48596
- }
48597
- return sqlanvil.TableMetadata.create({
48598
- type: metadata.type === "TABLE"
48599
- ? sqlanvil.TableMetadata.Type.TABLE
48600
- : metadata.type === "VIEW"
48601
- ? sqlanvil.TableMetadata.Type.VIEW
48602
- : sqlanvil.TableMetadata.Type.UNKNOWN,
48603
- target,
48604
- fields: (_a = metadata.schema.fields) === null || _a === void 0 ? void 0 : _a.map(field => convertField(field)),
48605
- lastUpdatedMillis: Long__default["default"].fromString(metadata.lastModifiedTime),
48606
- description: metadata.description,
48607
- labels: metadata.labels,
48608
- bigquery: {
48609
- hasStreamingBuffer: !!metadata.streamingBuffer
48610
- }
48611
- });
48612
- }
48613
- async deleteTable(target) {
48614
- await this.getClient(target.database)
48615
- .dataset(target.schema)
48616
- .table(target.name)
48617
- .delete({ ignoreNotFound: true });
48618
- }
48619
- async schemas(database) {
48620
- const data = await this.getClient(database).getDatasets();
48621
- return data[0].map(dataset => dataset.id);
48622
- }
48623
- async createSchema(database, schema) {
48624
- await this.execute(`create schema if not exists \`${database || this.bigQueryCredentials.projectId}.${schema}\``, { bigquery: { location: this.bigQueryCredentials.location } });
48625
- }
48626
- async setMetadata(action) {
48627
- const { target, actionDescriptor } = action;
48628
- const metadata = await this.getMetadata(target);
48629
- const schemaWithDescription = addDescriptionToMetadata(actionDescriptor.columns, metadata.schema.fields);
48630
- await this.getClient(target.database)
48631
- .dataset(target.schema)
48632
- .table(target.name)
48633
- .setMetadata({
48634
- description: actionDescriptor.description,
48635
- schema: schemaWithDescription,
48636
- labels: actionDescriptor.bigqueryLabels
48637
- });
48638
- }
48639
- async getMetadata(target) {
48640
- var _a, _b;
48641
- try {
48642
- const table = await this.getClient(target.database)
48643
- .dataset(target.schema)
48644
- .table(target.name)
48645
- .getMetadata();
48646
- return table === null || table === void 0 ? void 0 : table[0];
48647
- }
48648
- catch (e) {
48649
- if (((_b = (_a = e === null || e === void 0 ? void 0 : e.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.reason) === "notFound") {
48650
- return null;
48651
- }
48652
- throw coerceAsError(e);
48653
- }
48654
- }
48655
- getClient(projectId) {
48656
- if (this.bigqueryClient) {
48657
- return this.bigqueryClient;
48658
- }
48659
- projectId = projectId || this.bigQueryCredentials.projectId;
48660
- if (!this.clients.has(projectId)) {
48661
- this.clients.set(projectId, new bigquery.BigQuery({
48662
- projectId,
48663
- scopes: EXTRA_GOOGLE_SCOPES,
48664
- location: this.bigQueryCredentials.location,
48665
- credentials: this.bigQueryCredentials.credentials && JSON.parse(this.bigQueryCredentials.credentials)
48666
- }));
48667
- }
48668
- return this.clients.get(projectId);
48669
- }
48670
- async runQuery(query, params, rowLimit, byteLimit, location) {
48671
- const results = await new Promise((resolve, reject) => {
48672
- const allRows = new LimitedResultSet({
48673
- rowLimit,
48674
- byteLimit
48675
- });
48676
- const stream = this.getClient().createQueryStream({
48677
- query,
48678
- params,
48679
- location
48680
- });
48681
- stream
48682
- .on("error", e => reject(coerceAsError(e)))
48683
- .on("data", row => {
48684
- if (!allRows.push(row)) {
48685
- stream.end();
48686
- }
48687
- })
48688
- .on("end", () => {
48689
- resolve(allRows.rows);
48690
- });
48691
- });
48692
- return { rows: cleanRows(results), metadata: {} };
48693
- }
48694
- prepareQueryOptions(query, rowLimit, bigqueryOptions, params) {
48695
- return {
48696
- query,
48697
- useLegacySql: false,
48698
- jobPrefix: "sqlanvil-" + ((bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.jobPrefix) ? `${bigqueryOptions.jobPrefix}-` : ""),
48699
- location: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.location,
48700
- maxResults: rowLimit,
48701
- labels: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.labels,
48702
- dryRun: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.dryRun,
48703
- reservation: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.reservation,
48704
- params
48705
- };
48706
- }
48707
- async createQueryJob(query, params, rowLimit, byteLimit, onCancel, labels, location, jobPrefix, dryRun, reservation) {
48708
- let isCancelled = false;
48709
- onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => (isCancelled = true));
48710
- return retry(async () => {
48711
- try {
48712
- const job = await this.getClient().createQueryJob(this.prepareQueryOptions(query, rowLimit, {
48713
- labels,
48714
- location,
48715
- jobPrefix,
48716
- dryRun,
48717
- reservation
48718
- }, params));
48719
- const resultStream = job[0].getQueryResultsStream();
48720
- return new Promise((resolve, reject) => {
48721
- if (isCancelled) {
48722
- resultStream.end();
48723
- reject(new Error("Query cancelled."));
48724
- return;
48725
- }
48726
- onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => {
48727
- resultStream.end();
48728
- reject(new Error("Query cancelled."));
48729
- });
48730
- const results = new LimitedResultSet({
48731
- rowLimit,
48732
- byteLimit
48733
- });
48734
- resultStream
48735
- .on("error", async (e) => {
48736
- var _a, _b;
48737
- if (dryRun && ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Not found: Job"))) {
48738
- resolve({ rows: [], metadata: {} });
48739
- return;
48740
- }
48741
- try {
48742
- const [jobMetadata] = await job[0].getMetadata();
48743
- if (!!((_b = jobMetadata.status) === null || _b === void 0 ? void 0 : _b.errorResult)) {
48744
- const error = createBigQueryError(jobMetadata);
48745
- reject(error);
48746
- }
48747
- }
48748
- catch (metadataError) {
48749
- reject(metadataError);
48750
- }
48751
- reject(e);
48752
- })
48753
- .on("data", row => {
48754
- if (!results.push(row)) {
48755
- resultStream.end();
48756
- }
48757
- })
48758
- .on("end", async () => {
48759
- var _a;
48760
- try {
48761
- const [jobMetadata] = await job[0].getMetadata();
48762
- if (!!((_a = jobMetadata.status) === null || _a === void 0 ? void 0 : _a.errorResult)) {
48763
- const error = createBigQueryError(jobMetadata);
48764
- reject(error);
48765
- return;
48766
- }
48767
- resolve({
48768
- rows: results.rows,
48769
- metadata: {
48770
- bigquery: {
48771
- jobId: jobMetadata.jobReference.jobId,
48772
- totalBytesBilled: jobMetadata.statistics.query.totalBytesBilled
48773
- ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesBilled)
48774
- : Long__default["default"].ZERO,
48775
- totalBytesProcessed: jobMetadata.statistics.query.totalBytesProcessed
48776
- ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesProcessed)
48777
- : Long__default["default"].ZERO,
48778
- }
48779
- }
48780
- });
48781
- }
48782
- catch (e) {
48783
- reject(e);
48784
- }
48785
- });
48786
- });
48787
- }
48788
- catch (e) {
48789
- throw coerceAsError(e);
48790
- }
48791
- }, BIGQUERY_INTERNAL_ERROR_JOB_MAX_ATTEMPTS, e => { var _a; return (_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Retrying the job may solve the problem"); });
48792
- }
48793
- }
48794
- function cleanRows(rows) {
48795
- if (rows.length === 0) {
48796
- return rows;
48797
- }
48798
- const sampleData = rows[0];
48799
- const fieldsWithBigQueryDates = Object.keys(sampleData).filter(key => sampleData[key] &&
48800
- sampleData[key].constructor &&
48801
- BIGQUERY_DATE_RELATED_FIELDS.includes(sampleData[key].constructor.name));
48802
- fieldsWithBigQueryDates.forEach(dateField => {
48803
- rows.forEach(row => (row[dateField] = row[dateField] ? row[dateField].value : row[dateField]));
48804
- });
48805
- return rows;
48806
- }
48807
- function convertField(field) {
48808
- const result = {
48809
- name: field.name,
48810
- flags: field.mode === "REPEATED" ? [sqlanvil.Field.Flag.REPEATED] : [],
48811
- description: field.description
48812
- };
48813
- if (field.type === "RECORD" || field.type === "STRUCT") {
48814
- result.struct = sqlanvil.Fields.create({
48815
- fields: field.fields.map(innerField => convertField(innerField))
50465
+ kind: "table",
50466
+ type: tableType(table.enumType),
50467
+ target: table.target,
50468
+ table,
50469
+ action: table
48816
50470
  });
48817
50471
  }
48818
- else {
48819
- result.primitive = convertFieldType$2(field.type);
50472
+ for (const assertion of compiledGraph.assertions || []) {
50473
+ nodes.push({
50474
+ key: targetKey(assertion.target),
50475
+ dependencyKeys: depKeys(assertion.dependencyTargets),
50476
+ kind: "assertion",
50477
+ type: "assertion",
50478
+ target: assertion.target,
50479
+ action: assertion
50480
+ });
48820
50481
  }
48821
- return sqlanvil.Field.create(result);
48822
- }
48823
- function convertFieldType$2(type) {
48824
- switch (String(type).toUpperCase()) {
48825
- case "FLOAT":
48826
- case "FLOAT64":
48827
- return sqlanvil.Field.Primitive.FLOAT;
48828
- case "INTEGER":
48829
- case "INT64":
48830
- return sqlanvil.Field.Primitive.INTEGER;
48831
- case "NUMERIC":
48832
- return sqlanvil.Field.Primitive.NUMERIC;
48833
- case "BOOL":
48834
- case "BOOLEAN":
48835
- return sqlanvil.Field.Primitive.BOOLEAN;
48836
- case "STRING":
48837
- return sqlanvil.Field.Primitive.STRING;
48838
- case "DATE":
48839
- return sqlanvil.Field.Primitive.DATE;
48840
- case "DATETIME":
48841
- return sqlanvil.Field.Primitive.DATETIME;
48842
- case "TIMESTAMP":
48843
- return sqlanvil.Field.Primitive.TIMESTAMP;
48844
- case "TIME":
48845
- return sqlanvil.Field.Primitive.TIME;
48846
- case "BYTES":
48847
- return sqlanvil.Field.Primitive.BYTES;
48848
- case "GEOGRAPHY":
48849
- return sqlanvil.Field.Primitive.GEOGRAPHY;
48850
- case "BIGNUMERIC":
48851
- return sqlanvil.Field.Primitive.BIGNUMERIC;
48852
- case "JSON":
48853
- return sqlanvil.Field.Primitive.JSON;
48854
- case "INTERVAL":
48855
- return sqlanvil.Field.Primitive.INTERVAL;
48856
- default:
48857
- return sqlanvil.Field.Primitive.UNKNOWN;
50482
+ for (const operation of compiledGraph.operations || []) {
50483
+ if (!operation.target) {
50484
+ continue;
50485
+ }
50486
+ nodes.push({
50487
+ key: targetKey(operation.target),
50488
+ dependencyKeys: depKeys(operation.dependencyTargets),
50489
+ kind: "operation",
50490
+ type: "operation",
50491
+ target: operation.target,
50492
+ action: undefined
50493
+ });
48858
50494
  }
48859
- }
48860
- function addDescriptionToMetadata(columnDescriptions, metadataArray) {
48861
- if (!columnDescriptions) {
48862
- return metadataArray;
50495
+ for (const imp of compiledGraph.imports || []) {
50496
+ if (!imp.target) {
50497
+ continue;
50498
+ }
50499
+ nodes.push({
50500
+ key: targetKey(imp.target),
50501
+ dependencyKeys: depKeys(imp.dependencyTargets),
50502
+ kind: "import",
50503
+ type: "import",
50504
+ target: imp.target,
50505
+ action: undefined
50506
+ });
48863
50507
  }
48864
- const findDescription = (path) => columnDescriptions.find(column => column.path.join("") === path.join(""));
48865
- const mapDescriptionToMetadata = (metadata, path) => {
48866
- var _a;
48867
- const description = findDescription(path);
48868
- if (description) {
48869
- metadata.description = description.description;
48870
- if (((_a = description.bigqueryPolicyTags) === null || _a === void 0 ? void 0 : _a.length) > 0) {
48871
- metadata.policyTags = {
48872
- names: description.bigqueryPolicyTags
48873
- };
48874
- }
50508
+ const ordered = topoOrder(nodes);
50509
+ const shadowSchemas = Array.from(new Set(nodes.filter(n => n.kind === "table").map(n => n.target.schema)));
50510
+ const statusByKey = new Map();
50511
+ const results = [];
50512
+ try {
50513
+ for (const schema of shadowSchemas) {
50514
+ await deps.execute(deps.createSchemaSql(schema));
48875
50515
  }
48876
- if (metadata.fields) {
48877
- metadata.fields = metadata.fields.map(nestedMetadata => mapDescriptionToMetadata(nestedMetadata, [...path, nestedMetadata.name]));
50516
+ for (const node of ordered) {
50517
+ if (node.kind === "operation" || node.kind === "import") {
50518
+ statusByKey.set(node.key, "SKIPPED");
50519
+ results.push({ target: node.target, type: node.type, status: "SKIPPED", errors: [] });
50520
+ continue;
50521
+ }
50522
+ if (dependencyBlocked(node.dependencyKeys, statusByKey)) {
50523
+ statusByKey.set(node.key, "BLOCKED");
50524
+ results.push({ target: node.target, type: node.type, status: "BLOCKED", errors: [] });
50525
+ continue;
50526
+ }
50527
+ const evaluations = await deps.evaluate(node.action);
50528
+ const failed = evaluations.some(e => e.status === sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE);
50529
+ const status = failed ? "FAILURE" : "PASS";
50530
+ statusByKey.set(node.key, status);
50531
+ results.push({ target: node.target, type: node.type, status, errors: evaluations });
50532
+ if (status === "PASS" && node.kind === "table") {
50533
+ try {
50534
+ await deps.execute(deps.validationStubSql(node.table));
50535
+ }
50536
+ catch (e) {
50537
+ }
50538
+ }
48878
50539
  }
48879
- return metadata;
48880
- };
48881
- const newMetadata = metadataArray.map(metaItem => mapDescriptionToMetadata(metaItem, [metaItem.name]));
48882
- return newMetadata;
48883
- }
48884
- function createBigQueryError(jobMetadata) {
48885
- const error = new Error(jobMetadata.status.errorResult.message);
48886
- if (jobMetadata.jobReference && jobMetadata.jobReference.jobId) {
48887
- error.metadata = {
48888
- bigquery: {
48889
- jobId: jobMetadata.jobReference.jobId,
50540
+ }
50541
+ finally {
50542
+ if (!options.keepShadow) {
50543
+ for (const schema of shadowSchemas.slice().reverse()) {
50544
+ try {
50545
+ await deps.execute(deps.dropSchemaCascadeSql(schema));
50546
+ }
50547
+ catch (e) {
50548
+ }
48890
50549
  }
48891
- };
50550
+ }
48892
50551
  }
48893
- return error;
50552
+ return results;
48894
50553
  }
48895
50554
 
48896
50555
  class MySqlPoolExecutor {
@@ -48935,7 +50594,7 @@ class MySqlPoolExecutor {
48935
50594
  await this.pool.end();
48936
50595
  }
48937
50596
  }
48938
- function convertFieldType$1(type) {
50597
+ function convertFieldType(type) {
48939
50598
  switch (String(type).toUpperCase()) {
48940
50599
  case "FLOAT":
48941
50600
  case "DOUBLE":
@@ -49017,7 +50676,7 @@ function defaultClause(col, extra) {
49017
50676
  return ` DEFAULT '${escapeMysqlString(d)}'`;
49018
50677
  }
49019
50678
 
49020
- const INTERNAL_SCHEMAS$1 = new Set([
50679
+ const INTERNAL_SCHEMAS = new Set([
49021
50680
  "information_schema",
49022
50681
  "mysql",
49023
50682
  "performance_schema",
@@ -49162,7 +50821,7 @@ class MySqlDbAdapter {
49162
50821
  const comment = String((_b = (_a = row.column_comment) !== null && _a !== void 0 ? _a : row.COLUMN_COMMENT) !== null && _b !== void 0 ? _b : "");
49163
50822
  return sqlanvil.Field.create({
49164
50823
  name: ((_c = row.column_name) !== null && _c !== void 0 ? _c : row.COLUMN_NAME),
49165
- primitive: convertFieldType$1(((_d = row.data_type) !== null && _d !== void 0 ? _d : row.DATA_TYPE)),
50824
+ primitive: convertFieldType(((_d = row.data_type) !== null && _d !== void 0 ? _d : row.DATA_TYPE)),
49166
50825
  description: comment || undefined
49167
50826
  });
49168
50827
  })
@@ -49184,7 +50843,7 @@ class MySqlDbAdapter {
49184
50843
  });
49185
50844
  return result.rows
49186
50845
  .map(row => { var _a; return ((_a = row.schema_name) !== null && _a !== void 0 ? _a : row.SCHEMA_NAME); })
49187
- .filter(name => !INTERNAL_SCHEMAS$1.has(name));
50846
+ .filter(name => !INTERNAL_SCHEMAS.has(name));
49188
50847
  }
49189
50848
  async createSchema(_database, schema) {
49190
50849
  await this.execute(`create database if not exists \`${schema}\``, {
@@ -49248,372 +50907,6 @@ class MySqlDbAdapter {
49248
50907
  }
49249
50908
  }
49250
50909
 
49251
- const maybeInitializePg = (() => {
49252
- let initialized = false;
49253
- return () => {
49254
- if (!initialized) {
49255
- initialized = true;
49256
- pg__namespace.types.setTypeParser(20, Number);
49257
- }
49258
- };
49259
- })();
49260
- class PgPoolExecutor {
49261
- constructor(clientConfig, options) {
49262
- maybeInitializePg();
49263
- this.pool = new pg__namespace.Pool(Object.assign(Object.assign({}, clientConfig), { max: options === null || options === void 0 ? void 0 : options.concurrencyLimit }));
49264
- this.pool.on("error", err => {
49265
- console.error("pg.Pool idle client error", err.message, err.stack);
49266
- });
49267
- }
49268
- async verifyConnection() {
49269
- const client = await this.pool.connect();
49270
- try {
49271
- await client.query("select 1");
49272
- }
49273
- finally {
49274
- client.release();
49275
- }
49276
- }
49277
- async withClientLock(callback) {
49278
- const client = await this.pool.connect();
49279
- let released = false;
49280
- const releaseOnce = (err) => {
49281
- if (released) {
49282
- return;
49283
- }
49284
- released = true;
49285
- try {
49286
- client.release(err);
49287
- }
49288
- catch (e) {
49289
- console.error("Error thrown when releasing pg.Client", e.message, e.stack);
49290
- }
49291
- };
49292
- try {
49293
- client.on("error", err => {
49294
- console.error("pg.Client client error", err.message, err.stack);
49295
- releaseOnce(err);
49296
- });
49297
- return await callback({
49298
- execute: async (statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
49299
- return await new Promise((resolve, reject) => {
49300
- var _a;
49301
- const query = client.query(new QueryStream__default["default"](statement, options === null || options === void 0 ? void 0 : options.params));
49302
- const results = new LimitedResultSet({
49303
- rowLimit: options === null || options === void 0 ? void 0 : options.rowLimit,
49304
- byteLimit: options === null || options === void 0 ? void 0 : options.byteLimit
49305
- });
49306
- (_a = options === null || options === void 0 ? void 0 : options.onCancel) === null || _a === void 0 ? void 0 : _a.call(options, () => query.destroy(new Error("Query cancelled.")));
49307
- query.on("data", (row) => {
49308
- try {
49309
- verifyUniqueColumnNames(query.cursor._result.fields);
49310
- }
49311
- catch (e) {
49312
- query.destroy(e);
49313
- return;
49314
- }
49315
- if (!results.push(row)) {
49316
- query.cursor.close();
49317
- }
49318
- });
49319
- query.on("error", err => {
49320
- releaseOnce(err);
49321
- reject(err);
49322
- });
49323
- query.on("end", () => {
49324
- resolve(results.rows);
49325
- });
49326
- });
49327
- }
49328
- });
49329
- }
49330
- finally {
49331
- releaseOnce();
49332
- }
49333
- }
49334
- async close() {
49335
- await this.pool.end();
49336
- }
49337
- }
49338
- function verifyUniqueColumnNames(fields) {
49339
- const colNames = new Set();
49340
- fields.forEach(field => {
49341
- if (colNames.has(field.name)) {
49342
- throw new Error(`Ambiguous column name: ${field.name}`);
49343
- }
49344
- colNames.add(field.name);
49345
- });
49346
- }
49347
- function convertFieldType(type) {
49348
- switch (String(type).toUpperCase()) {
49349
- case "FLOAT":
49350
- case "FLOAT4":
49351
- case "FLOAT8":
49352
- case "DOUBLE PRECISION":
49353
- case "REAL":
49354
- return sqlanvil.Field.Primitive.FLOAT;
49355
- case "INTEGER":
49356
- case "INT":
49357
- case "INT2":
49358
- case "INT4":
49359
- case "INT8":
49360
- case "BIGINT":
49361
- case "SMALLINT":
49362
- return sqlanvil.Field.Primitive.INTEGER;
49363
- case "DECIMAL":
49364
- case "NUMERIC":
49365
- return sqlanvil.Field.Primitive.NUMERIC;
49366
- case "BOOLEAN":
49367
- case "BOOL":
49368
- return sqlanvil.Field.Primitive.BOOLEAN;
49369
- case "STRING":
49370
- case "VARCHAR":
49371
- case "CHAR":
49372
- case "CHARACTER":
49373
- case "CHARACTER VARYING":
49374
- case "NVARCHAR":
49375
- case "TEXT":
49376
- case "NCHAR":
49377
- case "BPCHAR":
49378
- return sqlanvil.Field.Primitive.STRING;
49379
- case "DATE":
49380
- return sqlanvil.Field.Primitive.DATE;
49381
- case "TIMESTAMP":
49382
- case "TIMESTAMPZ":
49383
- case "TIMESTAMP WITHOUT TIME ZONE":
49384
- case "TIMESTAMP WITH TIME ZONE":
49385
- return sqlanvil.Field.Primitive.TIMESTAMP;
49386
- default:
49387
- return sqlanvil.Field.Primitive.UNKNOWN;
49388
- }
49389
- }
49390
-
49391
- const INTERNAL_SCHEMAS = new Set(["information_schema", "pg_catalog", "pg_internal", "pg_toast"]);
49392
- class PostgresDbAdapter {
49393
- constructor(queryExecutor) {
49394
- this.queryExecutor = queryExecutor;
49395
- }
49396
- static async create(credentials, options) {
49397
- const sslMode = (credentials.sslMode || "").toLowerCase();
49398
- const sslEnabled = !(options === null || options === void 0 ? void 0 : options.disableSslForTestsOnly) && sslMode !== "disable";
49399
- const clientConfig = {
49400
- host: credentials.host,
49401
- port: credentials.port,
49402
- database: credentials.database,
49403
- user: credentials.user,
49404
- password: credentials.password,
49405
- ssl: sslEnabled
49406
- ? {
49407
- rejectUnauthorized: sslMode === "verify-ca" || sslMode === "verify-full"
49408
- }
49409
- : false
49410
- };
49411
- const queryExecutor = new PgPoolExecutor(clientConfig, options);
49412
- try {
49413
- await queryExecutor.verifyConnection();
49414
- }
49415
- catch (e) {
49416
- await queryExecutor.close().catch(() => undefined);
49417
- throw new ErrorWithCause(`Could not connect to Postgres at ${credentials.host}:${credentials.port} ` +
49418
- `as "${credentials.user}": ${e.message}`, e);
49419
- }
49420
- return new PostgresDbAdapter(queryExecutor);
49421
- }
49422
- async execute(statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) {
49423
- return await this.withClientLock(client => client.execute(statement, options));
49424
- }
49425
- async executeRaw(statement, options = { rowLimit: 1000 }) {
49426
- const result = await this.execute(statement, options);
49427
- return Object.assign(Object.assign({}, result), { schema: [] });
49428
- }
49429
- async withClientLock(callback) {
49430
- return await this.queryExecutor.withClientLock(client => callback({
49431
- execute: async (stmt, opts = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
49432
- try {
49433
- const rows = await client.execute(stmt, opts);
49434
- return { rows, metadata: {} };
49435
- }
49436
- catch (e) {
49437
- if (opts.includeQueryInError) {
49438
- throw new Error(`Error encountered while running "${stmt}": ${e.message}`);
49439
- }
49440
- throw new ErrorWithCause(`Error executing postgres query: ${e.message}`, e);
49441
- }
49442
- },
49443
- executeRaw: async (stmt, opts = { rowLimit: 1000 }) => {
49444
- const positional = opts.params ? Object.values(opts.params) : undefined;
49445
- const rows = await client.execute(stmt, { params: positional, rowLimit: opts.rowLimit });
49446
- return { rows, schema: [], metadata: {} };
49447
- }
49448
- }));
49449
- }
49450
- async evaluate(queryOrAction) {
49451
- const validationQueries = collectEvaluationQueries(queryOrAction, false, (query) => !!query ? `explain ${query}` : "").map((validationQuery, index) => ({ index, validationQuery }));
49452
- const validationQueriesWithoutWrappers = collectEvaluationQueries(queryOrAction, false);
49453
- const queryEvaluations = new Array();
49454
- for (const { index, validationQuery } of validationQueries) {
49455
- let evaluationResponse = {
49456
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS
49457
- };
49458
- try {
49459
- await this.execute(validationQuery.query);
49460
- }
49461
- catch (e) {
49462
- evaluationResponse = {
49463
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
49464
- error: parsePostgresEvalError(validationQuery.query, e)
49465
- };
49466
- }
49467
- queryEvaluations.push(sqlanvil.QueryEvaluation.create(Object.assign(Object.assign({}, evaluationResponse), { incremental: validationQuery.incremental, query: validationQueriesWithoutWrappers[index].query })));
49468
- }
49469
- return queryEvaluations;
49470
- }
49471
- async tables(_database, schema) {
49472
- const params = [];
49473
- let schemaClause = "";
49474
- let matviewSchemaClause = "";
49475
- if (schema) {
49476
- schemaClause = "and table_schema = $1";
49477
- matviewSchemaClause = "and schemaname = $1";
49478
- params.push(schema);
49479
- }
49480
- const queryResult = await this.execute(`select table_name, table_schema
49481
- from information_schema.tables
49482
- where table_schema not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
49483
- ${schemaClause}
49484
- union
49485
- select matviewname as table_name, schemaname as table_schema
49486
- from pg_matviews
49487
- where schemaname not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
49488
- ${matviewSchemaClause}`, { params, rowLimit: 10000, includeQueryInError: true });
49489
- const targets = queryResult.rows.map(row => ({
49490
- schema: row.table_schema,
49491
- name: row.table_name
49492
- }));
49493
- return await Promise.all(targets.map(target => this.table(target)));
49494
- }
49495
- async search(searchText, options = { limit: 1000 }) {
49496
- const results = await this.execute(`select tables.table_schema as table_schema, tables.table_name as table_name
49497
- from information_schema.tables as tables
49498
- left join information_schema.columns columns
49499
- on tables.table_schema = columns.table_schema
49500
- and tables.table_name = columns.table_name
49501
- where tables.table_schema ilike $1
49502
- or tables.table_name ilike $1
49503
- or columns.column_name ilike $1
49504
- group by 1, 2`, {
49505
- params: [`%${searchText}%`],
49506
- rowLimit: options.limit
49507
- });
49508
- return await Promise.all(results.rows.map(row => this.table({
49509
- schema: row.table_schema,
49510
- name: row.table_name
49511
- })));
49512
- }
49513
- async table(target) {
49514
- const params = [target.schema, target.name];
49515
- const [tableResults, columnResults, descriptionResults, matviewResults, matviewColumns] = await Promise.all([
49516
- this.execute(`select table_type from information_schema.tables where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49517
- this.execute(`select column_name, data_type, is_nullable, ordinal_position
49518
- from information_schema.columns
49519
- where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49520
- this.execute(`select objsubid as column_number, description
49521
- from pg_description
49522
- where objoid = (
49523
- select oid from pg_class where relname = $2 and relnamespace = (
49524
- select oid from pg_namespace where nspname = $1
49525
- )
49526
- )`, { params, includeQueryInError: true }),
49527
- this.execute(`select 1 from pg_matviews where schemaname = $1 and matviewname = $2`, { params, includeQueryInError: true }),
49528
- this.execute(`select a.attname as column_name, format_type(a.atttypid, a.atttypmod) as data_type,
49529
- a.attnum as ordinal_position
49530
- from pg_attribute a
49531
- join pg_class c on c.oid = a.attrelid
49532
- join pg_namespace n on n.oid = c.relnamespace
49533
- where n.nspname = $1 and c.relname = $2 and a.attnum > 0 and not a.attisdropped
49534
- order by a.attnum`, { params, includeQueryInError: true })
49535
- ]);
49536
- const findDescription = (columnNumber) => { var _a; return (_a = descriptionResults.rows.find(row => row.column_number === columnNumber)) === null || _a === void 0 ? void 0 : _a.description; };
49537
- if (tableResults.rows.length > 0) {
49538
- return sqlanvil.TableMetadata.create({
49539
- target,
49540
- type: tableResults.rows[0].table_type === "VIEW"
49541
- ? sqlanvil.TableMetadata.Type.VIEW
49542
- : sqlanvil.TableMetadata.Type.TABLE,
49543
- fields: columnResults.rows.map(row => sqlanvil.Field.create({
49544
- name: row.column_name,
49545
- primitive: convertFieldType(row.data_type),
49546
- description: findDescription(row.ordinal_position)
49547
- })),
49548
- description: findDescription(0)
49549
- });
49550
- }
49551
- if (matviewResults.rows.length > 0) {
49552
- return sqlanvil.TableMetadata.create({
49553
- target,
49554
- type: sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW,
49555
- fields: matviewColumns.rows.map(row => sqlanvil.Field.create({
49556
- name: row.column_name,
49557
- primitive: convertFieldType(String(row.data_type).replace(/\(.*\)/, "")),
49558
- description: findDescription(row.ordinal_position)
49559
- })),
49560
- description: findDescription(0)
49561
- });
49562
- }
49563
- return null;
49564
- }
49565
- async deleteTable(target) {
49566
- const metadata = await this.table(target);
49567
- if (!metadata) {
49568
- return;
49569
- }
49570
- const kind = metadata.type === sqlanvil.TableMetadata.Type.VIEW ? "view" : "table";
49571
- await this.execute(`drop ${kind} if exists "${target.schema}"."${target.name}" cascade`, { includeQueryInError: true });
49572
- }
49573
- async schemas(_database) {
49574
- const result = await this.execute(`select nspname from pg_namespace`, {
49575
- includeQueryInError: true
49576
- });
49577
- return result.rows
49578
- .map(row => row.nspname)
49579
- .filter(name => !INTERNAL_SCHEMAS.has(name) && !name.startsWith("pg_"));
49580
- }
49581
- async createSchema(_database, schema) {
49582
- await this.execute(`create schema if not exists "${schema}"`, {
49583
- includeQueryInError: true
49584
- });
49585
- }
49586
- async setMetadata(action) {
49587
- var _a;
49588
- const { target, actionDescriptor, tableType } = action;
49589
- const actualMetadata = await this.table(target);
49590
- if (!actualMetadata) {
49591
- return;
49592
- }
49593
- const relationKind = actualMetadata.type === sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW
49594
- ? "materialized view"
49595
- : tableType === "view"
49596
- ? "view"
49597
- : "table";
49598
- const queries = [];
49599
- if (actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.description) {
49600
- queries.push(this.execute(`comment on ${relationKind} "${target.schema}"."${target.name}" is '${actionDescriptor.description.replace(/'/g, "''")}'`));
49601
- }
49602
- if (((_a = actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.columns) === null || _a === void 0 ? void 0 : _a.length) > 0) {
49603
- actionDescriptor.columns
49604
- .filter(column => column.path.length === 1 &&
49605
- actualMetadata.fields.some(field => field.name === column.path[0]))
49606
- .forEach(column => {
49607
- queries.push(this.execute(`comment on column "${target.schema}"."${target.name}"."${column.path[0]}" is '${column.description.replace(/'/g, "''")}'`));
49608
- });
49609
- }
49610
- await Promise.all(queries);
49611
- }
49612
- async close() {
49613
- await this.queryExecutor.close();
49614
- }
49615
- }
49616
-
49617
50910
  class SupabaseDbAdapter extends PostgresDbAdapter {
49618
50911
  static async create(credentials, options) {
49619
50912
  const sslMode = (credentials.sslMode || "").toLowerCase();