@sqlanvil/cli 1.14.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 +2475 -1214
  2. package/package.json +1 -1
  3. package/worker_bundle.js +1330 -173
package/bundle.js CHANGED
@@ -34,11 +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');
38
37
  var googleAuthLibrary = require('google-auth-library');
39
38
  var promisePoolExecutor = require('promise-pool-executor');
40
39
  var sizeof = require('object-sizeof');
41
40
  var QueryStream = require('pg-query-stream');
41
+ var os = require('os');
42
42
  var readlineSync = require('readline-sync');
43
43
  var untildify = require('untildify');
44
44
  var googleSqlSyntaxTs = require('google-sql-syntax-ts');
@@ -81,9 +81,9 @@ var mysql__namespace = /*#__PURE__*/_interopNamespace(mysql);
81
81
  var pg__namespace = /*#__PURE__*/_interopNamespace(pg);
82
82
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
83
83
  var Long__default = /*#__PURE__*/_interopDefaultLegacy(Long);
84
- var os__namespace = /*#__PURE__*/_interopNamespace(os);
85
84
  var sizeof__default = /*#__PURE__*/_interopDefaultLegacy(sizeof);
86
85
  var QueryStream__default = /*#__PURE__*/_interopDefaultLegacy(QueryStream);
86
+ var os__namespace = /*#__PURE__*/_interopNamespace(os);
87
87
  var readlineSync__namespace = /*#__PURE__*/_interopNamespace(readlineSync);
88
88
  var untildify__default = /*#__PURE__*/_interopDefaultLegacy(untildify);
89
89
  var jsBeautify__namespace = /*#__PURE__*/_interopNamespace(jsBeautify);
@@ -1283,6 +1283,7 @@ const sqlanvil = $root.sqlanvil = (() => {
1283
1283
  * @property {number|null} [port] ConnectionConfig port
1284
1284
  * @property {string|null} [database] ConnectionConfig database
1285
1285
  * @property {string|null} [defaultSchema] ConnectionConfig defaultSchema
1286
+ * @property {string|null} [mode] ConnectionConfig mode
1286
1287
  */
1287
1288
 
1288
1289
  /**
@@ -1372,6 +1373,14 @@ const sqlanvil = $root.sqlanvil = (() => {
1372
1373
  */
1373
1374
  ConnectionConfig.prototype.defaultSchema = "";
1374
1375
 
1376
+ /**
1377
+ * ConnectionConfig mode.
1378
+ * @member {string} mode
1379
+ * @memberof sqlanvil.ConnectionConfig
1380
+ * @instance
1381
+ */
1382
+ ConnectionConfig.prototype.mode = "";
1383
+
1375
1384
  /**
1376
1385
  * Creates a new ConnectionConfig instance using the specified properties.
1377
1386
  * @function create
@@ -1414,6 +1423,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1414
1423
  writer.uint32(/* id 8, wireType 2 =*/66).string(message.defaultSchema);
1415
1424
  if (message.billingProject != null && Object.hasOwnProperty.call(message, "billingProject"))
1416
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);
1417
1428
  return writer;
1418
1429
  };
1419
1430
 
@@ -1490,6 +1501,10 @@ const sqlanvil = $root.sqlanvil = (() => {
1490
1501
  message.defaultSchema = reader.string();
1491
1502
  break;
1492
1503
  }
1504
+ case 10: {
1505
+ message.mode = reader.string();
1506
+ break;
1507
+ }
1493
1508
  default:
1494
1509
  reader.skipType(tag & 7, long);
1495
1510
  break;
@@ -1556,6 +1571,9 @@ const sqlanvil = $root.sqlanvil = (() => {
1556
1571
  if (message.defaultSchema != null && message.hasOwnProperty("defaultSchema"))
1557
1572
  if (!$util.isString(message.defaultSchema))
1558
1573
  return "defaultSchema: string expected";
1574
+ if (message.mode != null && message.hasOwnProperty("mode"))
1575
+ if (!$util.isString(message.mode))
1576
+ return "mode: string expected";
1559
1577
  return null;
1560
1578
  };
1561
1579
 
@@ -1593,6 +1611,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1593
1611
  message.database = String(object.database);
1594
1612
  if (object.defaultSchema != null)
1595
1613
  message.defaultSchema = String(object.defaultSchema);
1614
+ if (object.mode != null)
1615
+ message.mode = String(object.mode);
1596
1616
  return message;
1597
1617
  };
1598
1618
 
@@ -1619,6 +1639,7 @@ const sqlanvil = $root.sqlanvil = (() => {
1619
1639
  object.database = "";
1620
1640
  object.defaultSchema = "";
1621
1641
  object.billingProject = "";
1642
+ object.mode = "";
1622
1643
  }
1623
1644
  if (message.platform != null && message.hasOwnProperty("platform"))
1624
1645
  object.platform = message.platform;
@@ -1638,6 +1659,8 @@ const sqlanvil = $root.sqlanvil = (() => {
1638
1659
  object.defaultSchema = message.defaultSchema;
1639
1660
  if (message.billingProject != null && message.hasOwnProperty("billingProject"))
1640
1661
  object.billingProject = message.billingProject;
1662
+ if (message.mode != null && message.hasOwnProperty("mode"))
1663
+ object.mode = message.mode;
1641
1664
  return object;
1642
1665
  };
1643
1666
 
@@ -26390,6 +26413,668 @@ const sqlanvil = $root.sqlanvil = (() => {
26390
26413
  return Import;
26391
26414
  })();
26392
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
+
26393
27078
  sqlanvil.Assertion = (function() {
26394
27079
 
26395
27080
  /**
@@ -30366,6 +31051,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30366
31051
  * @property {Array.<sqlanvil.IDataPreparation>|null} [dataPreparations] CompiledGraph dataPreparations
30367
31052
  * @property {Array.<sqlanvil.IExport>|null} [exports] CompiledGraph exports
30368
31053
  * @property {Array.<sqlanvil.IImport>|null} [imports] CompiledGraph imports
31054
+ * @property {Array.<sqlanvil.IExtract>|null} [extracts] CompiledGraph extracts
30369
31055
  * @property {sqlanvil.IGraphErrors|null} [graphErrors] CompiledGraph graphErrors
30370
31056
  * @property {string|null} [sqlanvilCoreVersion] CompiledGraph sqlanvilCoreVersion
30371
31057
  * @property {Array.<sqlanvil.ITarget>|null} [targets] CompiledGraph targets
@@ -30390,6 +31076,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30390
31076
  this.dataPreparations = [];
30391
31077
  this.exports = [];
30392
31078
  this.imports = [];
31079
+ this.extracts = [];
30393
31080
  this.targets = [];
30394
31081
  if (properties)
30395
31082
  for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
@@ -30477,6 +31164,14 @@ const sqlanvil = $root.sqlanvil = (() => {
30477
31164
  */
30478
31165
  CompiledGraph.prototype.imports = $util.emptyArray;
30479
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
+
30480
31175
  /**
30481
31176
  * CompiledGraph graphErrors.
30482
31177
  * @member {sqlanvil.IGraphErrors|null|undefined} graphErrors
@@ -30571,6 +31266,9 @@ const sqlanvil = $root.sqlanvil = (() => {
30571
31266
  if (message.imports != null && message.imports.length)
30572
31267
  for (let i = 0; i < message.imports.length; ++i)
30573
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();
30574
31272
  return writer;
30575
31273
  };
30576
31274
 
@@ -30669,6 +31367,12 @@ const sqlanvil = $root.sqlanvil = (() => {
30669
31367
  message.imports.push($root.sqlanvil.Import.decode(reader, reader.uint32(), undefined, long + 1));
30670
31368
  break;
30671
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
+ }
30672
31376
  case 7: {
30673
31377
  message.graphErrors = $root.sqlanvil.GraphErrors.decode(reader, reader.uint32(), undefined, long + 1);
30674
31378
  break;
@@ -30812,6 +31516,15 @@ const sqlanvil = $root.sqlanvil = (() => {
30812
31516
  return "imports." + error;
30813
31517
  }
30814
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
+ }
30815
31528
  if (message.graphErrors != null && message.hasOwnProperty("graphErrors")) {
30816
31529
  let error = $root.sqlanvil.GraphErrors.verify(message.graphErrors, long + 1);
30817
31530
  if (error)
@@ -30948,6 +31661,16 @@ const sqlanvil = $root.sqlanvil = (() => {
30948
31661
  message.imports[i] = $root.sqlanvil.Import.fromObject(object.imports[i], long + 1);
30949
31662
  }
30950
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
+ }
30951
31674
  if (object.graphErrors != null) {
30952
31675
  if (typeof object.graphErrors !== "object")
30953
31676
  throw TypeError(".sqlanvil.CompiledGraph.graphErrors: object expected");
@@ -30997,6 +31720,7 @@ const sqlanvil = $root.sqlanvil = (() => {
30997
31720
  object.dataPreparations = [];
30998
31721
  object.exports = [];
30999
31722
  object.imports = [];
31723
+ object.extracts = [];
31000
31724
  }
31001
31725
  if (options.defaults) {
31002
31726
  object.projectConfig = null;
@@ -31062,6 +31786,11 @@ const sqlanvil = $root.sqlanvil = (() => {
31062
31786
  for (let j = 0; j < message.imports.length; ++j)
31063
31787
  object.imports[j] = $root.sqlanvil.Import.toObject(message.imports[j], options);
31064
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
+ }
31065
31794
  return object;
31066
31795
  };
31067
31796
 
@@ -36184,6 +36913,406 @@ const sqlanvil = $root.sqlanvil = (() => {
36184
36913
  return ImportSpec;
36185
36914
  })();
36186
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
+
36187
37316
  sqlanvil.ExecutionAction = (function() {
36188
37317
 
36189
37318
  /**
@@ -36201,6 +37330,7 @@ const sqlanvil = $root.sqlanvil = (() => {
36201
37330
  * @property {string|null} [jitCode] ExecutionAction jitCode
36202
37331
  * @property {sqlanvil.IExportSpec|null} ["export"] ExecutionAction export
36203
37332
  * @property {sqlanvil.IImportSpec|null} ["import"] ExecutionAction import
37333
+ * @property {sqlanvil.IExtractSpec|null} [extract] ExecutionAction extract
36204
37334
  */
36205
37335
 
36206
37336
  /**
@@ -36308,6 +37438,14 @@ const sqlanvil = $root.sqlanvil = (() => {
36308
37438
  */
36309
37439
  ExecutionAction.prototype["import"] = null;
36310
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
+
36311
37449
  /**
36312
37450
  * Creates a new ExecutionAction instance using the specified properties.
36313
37451
  * @function create
@@ -36356,6 +37494,8 @@ const sqlanvil = $root.sqlanvil = (() => {
36356
37494
  $root.sqlanvil.ExportSpec.encode(message["export"], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
36357
37495
  if (message["import"] != null && Object.hasOwnProperty.call(message, "import"))
36358
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();
36359
37499
  return writer;
36360
37500
  };
36361
37501
 
@@ -36444,6 +37584,10 @@ const sqlanvil = $root.sqlanvil = (() => {
36444
37584
  message["import"] = $root.sqlanvil.ImportSpec.decode(reader, reader.uint32(), undefined, long + 1);
36445
37585
  break;
36446
37586
  }
37587
+ case 15: {
37588
+ message.extract = $root.sqlanvil.ExtractSpec.decode(reader, reader.uint32(), undefined, long + 1);
37589
+ break;
37590
+ }
36447
37591
  default:
36448
37592
  reader.skipType(tag & 7, long);
36449
37593
  break;
@@ -36542,6 +37686,11 @@ const sqlanvil = $root.sqlanvil = (() => {
36542
37686
  if (error)
36543
37687
  return "import." + error;
36544
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
+ }
36545
37694
  return null;
36546
37695
  };
36547
37696
 
@@ -36629,6 +37778,11 @@ const sqlanvil = $root.sqlanvil = (() => {
36629
37778
  throw TypeError(".sqlanvil.ExecutionAction.import: object expected");
36630
37779
  message["import"] = $root.sqlanvil.ImportSpec.fromObject(object["import"], long + 1);
36631
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
+ }
36632
37786
  return message;
36633
37787
  };
36634
37788
 
@@ -36659,6 +37813,7 @@ const sqlanvil = $root.sqlanvil = (() => {
36659
37813
  object.jitCode = "";
36660
37814
  object["export"] = null;
36661
37815
  object["import"] = null;
37816
+ object.extract = null;
36662
37817
  }
36663
37818
  if (message.tasks && message.tasks.length) {
36664
37819
  object.tasks = [];
@@ -36688,6 +37843,8 @@ const sqlanvil = $root.sqlanvil = (() => {
36688
37843
  object["export"] = $root.sqlanvil.ExportSpec.toObject(message["export"], options);
36689
37844
  if (message["import"] != null && message.hasOwnProperty("import"))
36690
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);
36691
37848
  return object;
36692
37849
  };
36693
37850
 
@@ -46366,7 +47523,7 @@ function collectEvaluationQueries(queryOrAction, concatenate, queryModifier = (q
46366
47523
  .filter(validationQuery => !!validationQuery.query);
46367
47524
  }
46368
47525
 
46369
- const version = "1.14.0";
47526
+ const version = "1.15.0";
46370
47527
  const dataformVersion = "3.0.60";
46371
47528
 
46372
47529
  async function build(compiledGraph, runConfig, dbadapter) {
@@ -46390,7 +47547,7 @@ class Builder {
46390
47547
  this.warehouseState.tables.forEach(tableState => {
46391
47548
  tableMetadataByTarget.set(targetStringifier.stringify(tableState.target), tableState);
46392
47549
  });
46393
- 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)));
46394
47551
  return sqlanvil.ExecutionGraph.create({
46395
47552
  projectConfig: this.prunedGraph.projectConfig,
46396
47553
  runConfig: this.runConfig,
@@ -46426,6 +47583,17 @@ class Builder {
46426
47583
  options: imp.options
46427
47584
  }) });
46428
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
+ }
46429
47597
  toPartialExecutionAction(action) {
46430
47598
  return sqlanvil.ExecutionAction.create({
46431
47599
  target: action.target,
@@ -47085,318 +48253,1249 @@ function assertConnectionCredentialsAvailable(graph, connections) {
47085
48253
  }));
47086
48254
  }
47087
48255
 
47088
- function loadDuckdb() {
47089
- try {
47090
- return nativeRequire("@duckdb/node-api");
47091
- }
47092
- catch (e) {
47093
- throw new Error(`This feature requires the optional "@duckdb/node-api" dependency, which failed to load: ` +
47094
- `${e.message}`);
47095
- }
47096
- }
47097
- async function runAsync(conn, sql) {
47098
- await conn.run(sql);
47099
- }
47100
- async function allAsync(conn, sql) {
47101
- const reader = await conn.runAndReadAll(sql);
47102
- 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
+ });
47103
48260
  }
47104
- async function withDuckdb(fn, dbPath = ":memory:") {
47105
- const { DuckDBInstance } = loadDuckdb();
47106
- const instance = await DuckDBInstance.create(dbPath);
47107
- const conn = await instance.connect();
47108
- const done = () => {
47109
- var _a, _b;
47110
- try {
47111
- (_a = conn.closeSync) === null || _a === void 0 ? void 0 : _a.call(conn);
47112
- }
47113
- catch (e) {
47114
- }
47115
- try {
47116
- (_b = instance.closeSync) === null || _b === void 0 ? void 0 : _b.call(instance);
47117
- }
47118
- catch (e) {
47119
- }
47120
- };
48261
+ function parseBigqueryEvalError(error) {
48262
+ const evalError = sqlanvil.QueryEvaluationError.create({
48263
+ message: String(error)
48264
+ });
47121
48265
  try {
47122
- if (!process.env.HOME) {
47123
- 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 };
47124
48275
  }
47125
- const result = await fn(conn);
47126
- done();
47127
- return result;
47128
48276
  }
47129
- catch (e) {
47130
- done();
47131
- throw e;
48277
+ catch (_) {
47132
48278
  }
48279
+ return evalError;
47133
48280
  }
47134
48281
 
47135
- const PG_ATTACH_ALIAS = "pg";
47136
- const SECRET_NAME = "sa_export";
47137
- function buildAttachSql(pg, opts = {}) {
47138
- const readOnly = opts.readOnly !== false;
47139
- const dsn = [
47140
- pg.host && `host=${pg.host}`,
47141
- pg.port && `port=${pg.port}`,
47142
- pg.database && `dbname=${pg.database}`,
47143
- pg.user && `user=${pg.user}`,
47144
- pg.password && `password=${pg.password}`
47145
- ]
47146
- .filter(Boolean)
47147
- .join(" ");
47148
- const mode = readOnly ? ", READ_ONLY" : "";
47149
- return `ATTACH '${dsn}' AS ${PG_ATTACH_ALIAS} (TYPE postgres${mode})`;
47150
- }
47151
- function buildSecretSql(scheme, creds) {
47152
- if (scheme === "s3") {
47153
- const fields = [
47154
- "TYPE s3",
47155
- creds.accessKeyId && `KEY_ID '${creds.accessKeyId}'`,
47156
- creds.secretAccessKey && `SECRET '${creds.secretAccessKey}'`,
47157
- creds.region && `REGION '${creds.region}'`,
47158
- creds.endpoint && `ENDPOINT '${creds.endpoint}'`,
47159
- creds.endpoint && `URL_STYLE 'path'`,
47160
- creds.endpoint && `USE_SSL true`
47161
- ]
47162
- .filter(Boolean)
47163
- .join(", ");
47164
- return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
47165
- }
47166
- if (scheme === "gcs") {
47167
- const fields = [
47168
- "TYPE gcs",
47169
- creds.keyId && `KEY_ID '${creds.keyId}'`,
47170
- creds.secret && `SECRET '${creds.secret}'`
47171
- ]
47172
- .filter(Boolean)
47173
- .join(", ");
47174
- return `CREATE OR REPLACE SECRET ${SECRET_NAME} (${fields})`;
47175
- }
47176
- return null;
47177
- }
47178
- function toCopyTarget(uri) {
47179
- if (uri.startsWith("local://")) {
47180
- return uri.slice("local://".length);
48282
+ class LimitedResultSet {
48283
+ constructor(options) {
48284
+ this.options = options;
48285
+ this.results = [];
48286
+ this.currentBytes = 0;
47181
48287
  }
47182
- return uri;
47183
- }
47184
- function schemeOf(uri) {
47185
- if (uri.startsWith("s3://")) {
47186
- 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;
47187
48297
  }
47188
- if (uri.startsWith("gs://") || uri.startsWith("gcs://")) {
47189
- return "gcs";
48298
+ get rows() {
48299
+ return this.results;
47190
48300
  }
47191
- return "local";
47192
- }
47193
- function buildCopySql(selectSql, uri, format, options = {}) {
47194
- const target = toCopyTarget(uri);
47195
- const fmt = (format || "").toLowerCase();
47196
- const extraOptions = Object.entries(options || {}).map(([key, value]) => `${key.toUpperCase()} ${value}`);
47197
- const optionList = [`FORMAT ${fmt}`, ...extraOptions].join(", ");
47198
- return `COPY (SELECT * FROM postgres_query('${PG_ATTACH_ALIAS}', $sa$${selectSql}$sa$)) TO '${target}' (${optionList})`;
47199
48301
  }
47200
- async function runDuckdbExport(args) {
47201
- const { spec, selectSql, pg, storage, actionName } = args;
47202
- const uri = resolveExportUri(spec, actionName, { wildcard: false });
47203
- const scheme = schemeOf(uri);
47204
- if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
47205
- throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
47206
- `export to ${uri}.`);
47207
- }
47208
- return withDuckdb(async (conn) => {
47209
- await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
47210
- await runAsync(conn, buildAttachSql(pg));
47211
- if (scheme !== "local") {
47212
- const secret = buildSecretSql(scheme, storage[scheme]);
47213
- if (secret) {
47214
- 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;
47215
48312
  }
48313
+ lastErr = e;
47216
48314
  }
47217
- await runAsync(conn, buildCopySql(selectSql, uri, spec.format, spec.options || {}));
47218
- return { destination: toCopyTarget(uri) };
47219
- });
47220
- }
47221
-
47222
- function readerForFormat(format) {
47223
- switch ((format || "").toLowerCase()) {
47224
- case "csv":
47225
- return "read_csv_auto";
47226
- case "json":
47227
- return "read_json_auto";
47228
- case "parquet":
47229
- default:
47230
- return "read_parquet";
47231
48315
  }
48316
+ throw lastErr;
47232
48317
  }
47233
- function importTargetSql(target) {
47234
- return target.schema
47235
- ? `${PG_ATTACH_ALIAS}."${target.schema}"."${target.name}"`
47236
- : `${PG_ATTACH_ALIAS}."${target.name}"`;
47237
- }
47238
- function buildImportSql(target, location, format, overwrite) {
47239
- const reader = readerForFormat(format);
47240
- const source = toCopyTarget(location);
47241
- const dest = importTargetSql(target);
47242
- const select = `SELECT * FROM ${reader}('${source}')`;
47243
- if (overwrite) {
47244
- 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 });
47245
48330
  }
47246
- return [`INSERT INTO ${dest} ${select}`];
48331
+ return Object.assign(Object.assign({}, base), { credentials: credentials.credentials ? JSON.parse(credentials.credentials) : undefined });
47247
48332
  }
47248
- async function runDuckdbImport(args) {
47249
- const { spec, target, pg, storage } = args;
47250
- const location = spec.location || "";
47251
- const scheme = schemeOf(location);
47252
- if (scheme !== "local" && !(storage === null || storage === void 0 ? void 0 : storage[scheme])) {
47253
- throw new Error(`No "${scheme}" storage credentials found in .df-credentials.json (storage.${scheme}) for ` +
47254
- `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
+ });
47255
48350
  }
47256
- return withDuckdb(async (conn) => {
47257
- await runAsync(conn, "INSTALL postgres; LOAD postgres; INSTALL httpfs; LOAD httpfs;");
47258
- await runAsync(conn, buildAttachSql(pg, { readOnly: false }));
47259
- if (scheme !== "local") {
47260
- const secret = buildSecretSql(scheme, storage[scheme]);
47261
- if (secret) {
47262
- await runAsync(conn, secret);
47263
- }
47264
- }
47265
- for (const statement of buildImportSql(target, location, spec.format, spec.overwrite)) {
47266
- await runAsync(conn, statement);
47267
- }
47268
- return { source: toCopyTarget(location) };
47269
- });
47270
- }
47271
-
47272
- function parseArgvFlags(argv) {
47273
- const parsedArgv = {};
47274
- const splitArgv = [];
47275
- for (let arg of argv) {
47276
- if (arg.startsWith("--no-")) {
47277
- arg = `--${arg.slice(5)}=false`;
47278
- }
47279
- if (arg.startsWith("--") && arg.includes("=")) {
47280
- splitArgv.push(arg.slice(0, arg.indexOf("=")));
47281
- 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.");
47282
48355
  }
47283
- else {
47284
- splitArgv.push(arg);
48356
+ if (!statement) {
48357
+ throw new Error("Query string cannot be empty");
47285
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();
47286
48368
  }
47287
- let currentFlagName = "";
47288
- for (const splitArg of splitArgv) {
47289
- if (splitArg.startsWith("--")) {
47290
- currentFlagName = splitArg.slice(2);
47291
- parsedArgv[currentFlagName] = "";
47292
- }
47293
- else if (currentFlagName) {
47294
- parsedArgv[currentFlagName] = splitArg;
47295
- currentFlagName = "";
48369
+ async executeRaw(statement, options = { rowLimit: 1000 }) {
48370
+ if (!statement) {
48371
+ throw new Error("Query string cannot be empty");
47296
48372
  }
47297
- }
47298
- return parsedArgv;
47299
- }
47300
- class Flags {
47301
- static boolean(name, defaultValue = false) {
47302
- return new SingleValueFlag(name, defaultValue, (stringValue) => {
47303
- if (stringValue === "" || stringValue === "true") {
47304
- return true;
47305
- }
47306
- if (stringValue === "false") {
47307
- 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: {} };
47308
48380
  }
47309
- throw Flags.invalidFlagValueError(name);
47310
- });
47311
- }
47312
- static string(name, defaultValue = "") {
47313
- return new SingleValueFlag(name, defaultValue, (stringValue) => stringValue);
47314
- }
47315
- static number(name, defaultValue = 0) {
47316
- return new SingleValueFlag(name, defaultValue, (stringValue) => parseFloat(stringValue));
47317
- }
47318
- static long(name, defaultValue = Long__default["default"].ZERO) {
47319
- return new SingleValueFlag(name, defaultValue, Long__default["default"].fromString);
47320
- }
47321
- static stringSet(name, defaultValue = new Set()) {
47322
- return new SetFlag(name, defaultValue, (singleValue) => singleValue);
48381
+ })
48382
+ .promise();
47323
48383
  }
47324
- static getRawFlagValue(flagName) {
47325
- return Flags.parsedArgv[flagName];
48384
+ async withClientLock(callback) {
48385
+ return await callback(this);
47326
48386
  }
47327
- static setRawFlagValueForTesting(flagName, value) {
47328
- 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
+ }));
47329
48415
  }
47330
- static invalidFlagValueError(flagName) {
47331
- 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;
47332
48435
  }
47333
- }
47334
- Flags.parsedArgv = parseArgvFlags(process.argv);
47335
- class AbstractFlag {
47336
- constructor(name, defaultValue) {
47337
- this.name = name;
47338
- this.defaultValue = defaultValue;
47339
- 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
+ })));
47340
48452
  }
47341
- get() {
47342
- if (Flags.getRawFlagValue(this.name) === undefined) {
47343
- return this.defaultValue;
48453
+ async table(target) {
48454
+ var _a;
48455
+ const metadata = await this.getMetadata(target);
48456
+ if (!metadata) {
48457
+ return null;
47344
48458
  }
47345
- const stringValue = Flags.getRawFlagValue(this.name);
47346
- if (!(stringValue in this.parsed)) {
47347
- 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)}.`);
47348
48467
  }
47349
- 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
+ });
47350
48483
  }
47351
- }
47352
- class SingleValueFlag extends AbstractFlag {
47353
- constructor(name, defaultValue, parser) {
47354
- super(name, defaultValue);
47355
- 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 });
47356
48489
  }
47357
- parse(stringValue) {
47358
- return this.parser(stringValue);
48490
+ async schemas(database) {
48491
+ const data = await this.getClient(database).getDatasets();
48492
+ return data[0].map(dataset => dataset.id);
47359
48493
  }
47360
- }
47361
- class SetFlag extends AbstractFlag {
47362
- constructor(name, defaultValue, parser) {
47363
- super(name, defaultValue);
47364
- 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 } });
47365
48496
  }
47366
- parse(stringValue) {
47367
- return new Set(stringValue
47368
- .split(",")
47369
- .filter(singleValue => singleValue.length > 0)
47370
- .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
+ });
47371
48509
  }
47372
- }
47373
-
47374
- async function retry(fn, maxAttempts = 1, matchesRetriableError = () => true) {
47375
- let lastErr;
47376
- for (let i = 0; i < maxAttempts; i++) {
48510
+ async getMetadata(target) {
48511
+ var _a, _b;
47377
48512
  try {
47378
- 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];
47379
48518
  }
47380
48519
  catch (e) {
47381
- if (!matchesRetriableError(e)) {
47382
- 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;
47383
48522
  }
47384
- lastErr = e;
48523
+ throw coerceAsError(e);
47385
48524
  }
47386
48525
  }
47387
- throw lastErr;
47388
- }
47389
-
47390
- const CANCEL_EVENT = "jobCancel";
47391
- const flags = {
47392
- runnerNotificationPeriodMillis: Flags.number("runner-notification-period-millis", 5000)
47393
- };
47394
- const isSuccessfulAction = (actionResult) => actionResult.status === sqlanvil.ActionResult.ExecutionStatus.SUCCESSFUL ||
47395
- actionResult.status === sqlanvil.ActionResult.ExecutionStatus.DISABLED;
47396
- function run(dbadapter, graph, executionOptions, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
47397
- return new Runner(dbadapter, graph, executionOptions, partiallyExecutedRunResult, runnerNotificationPeriodMillis).execute();
47398
- }
47399
- class Runner {
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 {
47400
49499
  constructor(dbadapter, graph, executionOptions = {}, partiallyExecutedRunResult = {}, runnerNotificationPeriodMillis = flags.runnerNotificationPeriodMillis.get()) {
47401
49500
  var _a;
47402
49501
  this.dbadapter = dbadapter;
@@ -47704,6 +49803,24 @@ class Runner {
47704
49803
  taskResult.errorMessage = `${this.graph.projectConfig.warehouse} import error: ${e.message}`;
47705
49804
  }
47706
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
+ }
47707
49824
  else {
47708
49825
  try {
47709
49826
  const statement = this.executionOptions.connectionCredentials
@@ -48345,584 +50462,94 @@ async function validate(compiledGraph, deps, options = {}) {
48345
50462
  nodes.push({
48346
50463
  key: targetKey(table.target),
48347
50464
  dependencyKeys: depKeys(table.dependencyTargets),
48348
- kind: "table",
48349
- type: tableType(table.enumType),
48350
- target: table.target,
48351
- table,
48352
- action: table
48353
- });
48354
- }
48355
- for (const assertion of compiledGraph.assertions || []) {
48356
- nodes.push({
48357
- key: targetKey(assertion.target),
48358
- dependencyKeys: depKeys(assertion.dependencyTargets),
48359
- kind: "assertion",
48360
- type: "assertion",
48361
- target: assertion.target,
48362
- action: assertion
48363
- });
48364
- }
48365
- for (const operation of compiledGraph.operations || []) {
48366
- if (!operation.target) {
48367
- continue;
48368
- }
48369
- nodes.push({
48370
- key: targetKey(operation.target),
48371
- dependencyKeys: depKeys(operation.dependencyTargets),
48372
- kind: "operation",
48373
- type: "operation",
48374
- target: operation.target,
48375
- action: undefined
48376
- });
48377
- }
48378
- for (const imp of compiledGraph.imports || []) {
48379
- if (!imp.target) {
48380
- continue;
48381
- }
48382
- nodes.push({
48383
- key: targetKey(imp.target),
48384
- dependencyKeys: depKeys(imp.dependencyTargets),
48385
- kind: "import",
48386
- type: "import",
48387
- target: imp.target,
48388
- action: undefined
48389
- });
48390
- }
48391
- const ordered = topoOrder(nodes);
48392
- const shadowSchemas = Array.from(new Set(nodes.filter(n => n.kind === "table").map(n => n.target.schema)));
48393
- const statusByKey = new Map();
48394
- const results = [];
48395
- try {
48396
- for (const schema of shadowSchemas) {
48397
- await deps.execute(deps.createSchemaSql(schema));
48398
- }
48399
- for (const node of ordered) {
48400
- if (node.kind === "operation" || node.kind === "import") {
48401
- statusByKey.set(node.key, "SKIPPED");
48402
- results.push({ target: node.target, type: node.type, status: "SKIPPED", errors: [] });
48403
- continue;
48404
- }
48405
- if (dependencyBlocked(node.dependencyKeys, statusByKey)) {
48406
- statusByKey.set(node.key, "BLOCKED");
48407
- results.push({ target: node.target, type: node.type, status: "BLOCKED", errors: [] });
48408
- continue;
48409
- }
48410
- const evaluations = await deps.evaluate(node.action);
48411
- const failed = evaluations.some(e => e.status === sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE);
48412
- const status = failed ? "FAILURE" : "PASS";
48413
- statusByKey.set(node.key, status);
48414
- results.push({ target: node.target, type: node.type, status, errors: evaluations });
48415
- if (status === "PASS" && node.kind === "table") {
48416
- try {
48417
- await deps.execute(deps.validationStubSql(node.table));
48418
- }
48419
- catch (e) {
48420
- }
48421
- }
48422
- }
48423
- }
48424
- finally {
48425
- if (!options.keepShadow) {
48426
- for (const schema of shadowSchemas.slice().reverse()) {
48427
- try {
48428
- await deps.execute(deps.dropSchemaCascadeSql(schema));
48429
- }
48430
- catch (e) {
48431
- }
48432
- }
48433
- }
48434
- }
48435
- return results;
48436
- }
48437
-
48438
- function parsePostgresEvalError(_query, error) {
48439
- return sqlanvil.QueryEvaluationError.create({
48440
- message: (error === null || error === void 0 ? void 0 : error.message) ? String(error.message) : String(error)
48441
- });
48442
- }
48443
- function parseBigqueryEvalError(error) {
48444
- const evalError = sqlanvil.QueryEvaluationError.create({
48445
- message: String(error)
48446
- });
48447
- try {
48448
- if (!error.message) {
48449
- return evalError;
48450
- }
48451
- const bracketsString = error.message.split("[").slice(-1)[0];
48452
- const [_, lineNumber, columnNumber] = bracketsString.match(/([0-9]*)[^0-9]*([0-9]*).*/);
48453
- const line = Number(lineNumber);
48454
- const column = Number(columnNumber);
48455
- if (line || line === 0) {
48456
- evalError.errorLocation = { line, column };
48457
- }
48458
- }
48459
- catch (_) {
48460
- }
48461
- return evalError;
48462
- }
48463
-
48464
- class LimitedResultSet {
48465
- constructor(options) {
48466
- this.options = options;
48467
- this.results = [];
48468
- this.currentBytes = 0;
48469
- }
48470
- push(row) {
48471
- var _a, _b, _c, _d;
48472
- this.currentBytes += sizeof__default["default"](row);
48473
- 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)) ||
48474
- (((_c = this.options) === null || _c === void 0 ? void 0 : _c.byteLimit) && this.currentBytes >= ((_d = this.options) === null || _d === void 0 ? void 0 : _d.byteLimit))) {
48475
- return false;
48476
- }
48477
- this.results.push(row);
48478
- return true;
48479
- }
48480
- get rows() {
48481
- return this.results;
48482
- }
48483
- }
48484
-
48485
- const EXTRA_GOOGLE_SCOPES = ["https://www.googleapis.com/auth/drive"];
48486
- function bigQueryClientOptions(credentials, projectId) {
48487
- const base = {
48488
- projectId,
48489
- scopes: EXTRA_GOOGLE_SCOPES,
48490
- location: credentials.location
48491
- };
48492
- if (credentials.accessToken) {
48493
- const authClient = new googleAuthLibrary.OAuth2Client();
48494
- authClient.setCredentials({ access_token: credentials.accessToken });
48495
- return Object.assign(Object.assign({}, base), { authClient: authClient });
48496
- }
48497
- return Object.assign(Object.assign({}, base), { credentials: credentials.credentials ? JSON.parse(credentials.credentials) : undefined });
48498
- }
48499
- const BIGQUERY_DATE_RELATED_FIELDS = [
48500
- "BigQueryDate",
48501
- "BigQueryTime",
48502
- "BigQueryTimestamp",
48503
- "BigQueryDatetime"
48504
- ];
48505
- const BIGQUERY_INTERNAL_ERROR_JOB_MAX_ATTEMPTS = 3;
48506
- class BigQueryDbAdapter {
48507
- constructor(credentials, options) {
48508
- this.clients = new Map();
48509
- this.bigQueryCredentials = credentials;
48510
- this.bigqueryClient = options === null || options === void 0 ? void 0 : options.bigqueryClient;
48511
- this.pool = new promisePoolExecutor.PromisePoolExecutor({
48512
- concurrencyLimit: options === null || options === void 0 ? void 0 : options.concurrencyLimit,
48513
- frequencyWindow: 1000,
48514
- frequencyLimit: 30
48515
- });
48516
- }
48517
- async execute(statement, options = { interactive: false, rowLimit: 1000, byteLimit: 1024 * 1024 }) {
48518
- var _a;
48519
- 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)) {
48520
- throw new Error("BigQuery job labels may not be set for interactive queries.");
48521
- }
48522
- if (!statement) {
48523
- throw new Error("Query string cannot be empty");
48524
- }
48525
- return this.pool
48526
- .addSingleTask({
48527
- generator: () => {
48528
- var _a, _b, _c, _d, _e, _f;
48529
- 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)
48530
- : 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);
48531
- }
48532
- })
48533
- .promise();
48534
- }
48535
- async executeRaw(statement, options = { rowLimit: 1000 }) {
48536
- if (!statement) {
48537
- throw new Error("Query string cannot be empty");
48538
- }
48539
- return this.pool
48540
- .addSingleTask({
48541
- generator: async () => {
48542
- var _a, _b;
48543
- const [rows, , apiResponse] = await this.getClient().query(Object.assign(Object.assign({}, this.prepareQueryOptions(statement, options.rowLimit, options.bigquery, options.params)), { skipParsing: true }));
48544
- 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));
48545
- return { rows, schema, metadata: {} };
48546
- }
48547
- })
48548
- .promise();
48549
- }
48550
- async withClientLock(callback) {
48551
- return await callback(this);
48552
- }
48553
- async evaluate(queryOrAction) {
48554
- const validationQueries = collectEvaluationQueries(queryOrAction, true);
48555
- return await Promise.all(validationQueries.map(async ({ query, incremental }) => {
48556
- try {
48557
- await this.pool
48558
- .addSingleTask({
48559
- generator: () => this.getClient().query({
48560
- useLegacySql: false,
48561
- query,
48562
- dryRun: true
48563
- })
48564
- })
48565
- .promise();
48566
- return sqlanvil.QueryEvaluation.create({
48567
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS,
48568
- incremental,
48569
- query
48570
- });
48571
- }
48572
- catch (e) {
48573
- return {
48574
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
48575
- error: parseBigqueryEvalError(e),
48576
- incremental,
48577
- query
48578
- };
48579
- }
48580
- }));
48581
- }
48582
- async tables(database, schema) {
48583
- const datasetIds = schema ? [schema] : await this.schemas(database);
48584
- const tablesMetadata = [];
48585
- await Promise.all(datasetIds.map(async (datasetId) => {
48586
- const [tables] = await this.getClient(database)
48587
- .dataset(datasetId)
48588
- .getTables();
48589
- await Promise.all(tables.map(async (table) => {
48590
- const metadata = await this.table({
48591
- database,
48592
- schema: datasetId,
48593
- name: table.id
48594
- });
48595
- if (metadata) {
48596
- tablesMetadata.push(metadata);
48597
- }
48598
- }));
48599
- }));
48600
- return tablesMetadata;
48601
- }
48602
- async search(searchText, options = { limit: 1000 }) {
48603
- const results = await this.execute(`select table_catalog, table_schema, table_name
48604
- from region-${this.bigQueryCredentials.location}.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS
48605
- where regexp_contains(table_schema, @searchText) or regexp_contains(table_name, @searchText) or regexp_contains(field_path, @searchText)
48606
- group by 1, 2, 3`, {
48607
- params: {
48608
- searchText: `(?i)${searchText}`
48609
- },
48610
- interactive: true,
48611
- rowLimit: options.limit
48612
- });
48613
- return await Promise.all(results.rows.map(row => this.table({
48614
- database: row.table_catalog,
48615
- schema: row.table_schema,
48616
- name: row.table_name
48617
- })));
48618
- }
48619
- async table(target) {
48620
- var _a;
48621
- const metadata = await this.getMetadata(target);
48622
- if (!metadata) {
48623
- return null;
48624
- }
48625
- if (metadata.tableReference.datasetId !== target.schema ||
48626
- metadata.tableReference.tableId !== target.name) {
48627
- const metadataTarget = {
48628
- database: metadata.tableReference.projectId,
48629
- schema: metadata.tableReference.datasetId,
48630
- name: metadata.tableReference.tableId
48631
- };
48632
- throw new Error(`Target ${JSON.stringify(metadataTarget)} does not match requested target ${JSON.stringify(target)}.`);
48633
- }
48634
- return sqlanvil.TableMetadata.create({
48635
- type: metadata.type === "TABLE"
48636
- ? sqlanvil.TableMetadata.Type.TABLE
48637
- : metadata.type === "VIEW"
48638
- ? sqlanvil.TableMetadata.Type.VIEW
48639
- : sqlanvil.TableMetadata.Type.UNKNOWN,
48640
- target,
48641
- fields: (_a = metadata.schema.fields) === null || _a === void 0 ? void 0 : _a.map(field => convertField(field)),
48642
- lastUpdatedMillis: Long__default["default"].fromString(metadata.lastModifiedTime),
48643
- description: metadata.description,
48644
- labels: metadata.labels,
48645
- bigquery: {
48646
- hasStreamingBuffer: !!metadata.streamingBuffer
48647
- }
48648
- });
48649
- }
48650
- async deleteTable(target) {
48651
- await this.getClient(target.database)
48652
- .dataset(target.schema)
48653
- .table(target.name)
48654
- .delete({ ignoreNotFound: true });
48655
- }
48656
- async schemas(database) {
48657
- const data = await this.getClient(database).getDatasets();
48658
- return data[0].map(dataset => dataset.id);
48659
- }
48660
- async createSchema(database, schema) {
48661
- await this.execute(`create schema if not exists \`${database || this.bigQueryCredentials.projectId}.${schema}\``, { bigquery: { location: this.bigQueryCredentials.location } });
48662
- }
48663
- async setMetadata(action) {
48664
- const { target, actionDescriptor } = action;
48665
- const metadata = await this.getMetadata(target);
48666
- const schemaWithDescription = addDescriptionToMetadata(actionDescriptor.columns, metadata.schema.fields);
48667
- await this.getClient(target.database)
48668
- .dataset(target.schema)
48669
- .table(target.name)
48670
- .setMetadata({
48671
- description: actionDescriptor.description,
48672
- schema: schemaWithDescription,
48673
- labels: actionDescriptor.bigqueryLabels
48674
- });
48675
- }
48676
- async getMetadata(target) {
48677
- var _a, _b;
48678
- try {
48679
- const table = await this.getClient(target.database)
48680
- .dataset(target.schema)
48681
- .table(target.name)
48682
- .getMetadata();
48683
- return table === null || table === void 0 ? void 0 : table[0];
48684
- }
48685
- catch (e) {
48686
- 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") {
48687
- return null;
48688
- }
48689
- throw coerceAsError(e);
48690
- }
48691
- }
48692
- getClient(projectId) {
48693
- if (this.bigqueryClient) {
48694
- return this.bigqueryClient;
48695
- }
48696
- projectId = projectId || this.bigQueryCredentials.projectId;
48697
- if (!this.clients.has(projectId)) {
48698
- this.clients.set(projectId, new bigquery.BigQuery(bigQueryClientOptions(this.bigQueryCredentials, projectId)));
48699
- }
48700
- return this.clients.get(projectId);
48701
- }
48702
- async runQuery(query, params, rowLimit, byteLimit, location) {
48703
- const results = await new Promise((resolve, reject) => {
48704
- const allRows = new LimitedResultSet({
48705
- rowLimit,
48706
- byteLimit
48707
- });
48708
- const stream = this.getClient().createQueryStream({
48709
- query,
48710
- params,
48711
- location
48712
- });
48713
- stream
48714
- .on("error", e => reject(coerceAsError(e)))
48715
- .on("data", row => {
48716
- if (!allRows.push(row)) {
48717
- stream.end();
48718
- }
48719
- })
48720
- .on("end", () => {
48721
- resolve(allRows.rows);
48722
- });
48723
- });
48724
- return { rows: cleanRows(results), metadata: {} };
48725
- }
48726
- prepareQueryOptions(query, rowLimit, bigqueryOptions, params) {
48727
- return {
48728
- query,
48729
- useLegacySql: false,
48730
- jobPrefix: "sqlanvil-" + ((bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.jobPrefix) ? `${bigqueryOptions.jobPrefix}-` : ""),
48731
- location: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.location,
48732
- maxResults: rowLimit,
48733
- labels: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.labels,
48734
- dryRun: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.dryRun,
48735
- reservation: bigqueryOptions === null || bigqueryOptions === void 0 ? void 0 : bigqueryOptions.reservation,
48736
- params
48737
- };
48738
- }
48739
- async createQueryJob(query, params, rowLimit, byteLimit, onCancel, labels, location, jobPrefix, dryRun, reservation) {
48740
- let isCancelled = false;
48741
- onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => (isCancelled = true));
48742
- return retry(async () => {
48743
- try {
48744
- const job = await this.getClient().createQueryJob(this.prepareQueryOptions(query, rowLimit, {
48745
- labels,
48746
- location,
48747
- jobPrefix,
48748
- dryRun,
48749
- reservation
48750
- }, params));
48751
- const resultStream = job[0].getQueryResultsStream();
48752
- return new Promise((resolve, reject) => {
48753
- if (isCancelled) {
48754
- resultStream.end();
48755
- reject(new Error("Query cancelled."));
48756
- return;
48757
- }
48758
- onCancel === null || onCancel === void 0 ? void 0 : onCancel(() => {
48759
- resultStream.end();
48760
- reject(new Error("Query cancelled."));
48761
- });
48762
- const results = new LimitedResultSet({
48763
- rowLimit,
48764
- byteLimit
48765
- });
48766
- resultStream
48767
- .on("error", async (e) => {
48768
- var _a, _b;
48769
- if (dryRun && ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Not found: Job"))) {
48770
- resolve({ rows: [], metadata: {} });
48771
- return;
48772
- }
48773
- try {
48774
- const [jobMetadata] = await job[0].getMetadata();
48775
- if (!!((_b = jobMetadata.status) === null || _b === void 0 ? void 0 : _b.errorResult)) {
48776
- const error = createBigQueryError(jobMetadata);
48777
- reject(error);
48778
- }
48779
- }
48780
- catch (metadataError) {
48781
- reject(metadataError);
48782
- }
48783
- reject(e);
48784
- })
48785
- .on("data", row => {
48786
- if (!results.push(row)) {
48787
- resultStream.end();
48788
- }
48789
- })
48790
- .on("end", async () => {
48791
- var _a;
48792
- try {
48793
- const [jobMetadata] = await job[0].getMetadata();
48794
- if (!!((_a = jobMetadata.status) === null || _a === void 0 ? void 0 : _a.errorResult)) {
48795
- const error = createBigQueryError(jobMetadata);
48796
- reject(error);
48797
- return;
48798
- }
48799
- resolve({
48800
- rows: results.rows,
48801
- metadata: {
48802
- bigquery: {
48803
- jobId: jobMetadata.jobReference.jobId,
48804
- totalBytesBilled: jobMetadata.statistics.query.totalBytesBilled
48805
- ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesBilled)
48806
- : Long__default["default"].ZERO,
48807
- totalBytesProcessed: jobMetadata.statistics.query.totalBytesProcessed
48808
- ? Long__default["default"].fromString(jobMetadata.statistics.query.totalBytesProcessed)
48809
- : Long__default["default"].ZERO,
48810
- }
48811
- }
48812
- });
48813
- }
48814
- catch (e) {
48815
- reject(e);
48816
- }
48817
- });
48818
- });
48819
- }
48820
- catch (e) {
48821
- throw coerceAsError(e);
48822
- }
48823
- }, 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"); });
48824
- }
48825
- }
48826
- function cleanRows(rows) {
48827
- if (rows.length === 0) {
48828
- return rows;
48829
- }
48830
- const sampleData = rows[0];
48831
- const fieldsWithBigQueryDates = Object.keys(sampleData).filter(key => sampleData[key] &&
48832
- sampleData[key].constructor &&
48833
- BIGQUERY_DATE_RELATED_FIELDS.includes(sampleData[key].constructor.name));
48834
- fieldsWithBigQueryDates.forEach(dateField => {
48835
- rows.forEach(row => (row[dateField] = row[dateField] ? row[dateField].value : row[dateField]));
48836
- });
48837
- return rows;
48838
- }
48839
- function convertField(field) {
48840
- const result = {
48841
- name: field.name,
48842
- flags: field.mode === "REPEATED" ? [sqlanvil.Field.Flag.REPEATED] : [],
48843
- description: field.description
48844
- };
48845
- if (field.type === "RECORD" || field.type === "STRUCT") {
48846
- result.struct = sqlanvil.Fields.create({
48847
- fields: field.fields.map(innerField => convertField(innerField))
50465
+ kind: "table",
50466
+ type: tableType(table.enumType),
50467
+ target: table.target,
50468
+ table,
50469
+ action: table
48848
50470
  });
48849
50471
  }
48850
- else {
48851
- 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
+ });
48852
50481
  }
48853
- return sqlanvil.Field.create(result);
48854
- }
48855
- function convertFieldType$2(type) {
48856
- switch (String(type).toUpperCase()) {
48857
- case "FLOAT":
48858
- case "FLOAT64":
48859
- return sqlanvil.Field.Primitive.FLOAT;
48860
- case "INTEGER":
48861
- case "INT64":
48862
- return sqlanvil.Field.Primitive.INTEGER;
48863
- case "NUMERIC":
48864
- return sqlanvil.Field.Primitive.NUMERIC;
48865
- case "BOOL":
48866
- case "BOOLEAN":
48867
- return sqlanvil.Field.Primitive.BOOLEAN;
48868
- case "STRING":
48869
- return sqlanvil.Field.Primitive.STRING;
48870
- case "DATE":
48871
- return sqlanvil.Field.Primitive.DATE;
48872
- case "DATETIME":
48873
- return sqlanvil.Field.Primitive.DATETIME;
48874
- case "TIMESTAMP":
48875
- return sqlanvil.Field.Primitive.TIMESTAMP;
48876
- case "TIME":
48877
- return sqlanvil.Field.Primitive.TIME;
48878
- case "BYTES":
48879
- return sqlanvil.Field.Primitive.BYTES;
48880
- case "GEOGRAPHY":
48881
- return sqlanvil.Field.Primitive.GEOGRAPHY;
48882
- case "BIGNUMERIC":
48883
- return sqlanvil.Field.Primitive.BIGNUMERIC;
48884
- case "JSON":
48885
- return sqlanvil.Field.Primitive.JSON;
48886
- case "INTERVAL":
48887
- return sqlanvil.Field.Primitive.INTERVAL;
48888
- default:
48889
- 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
+ });
48890
50494
  }
48891
- }
48892
- function addDescriptionToMetadata(columnDescriptions, metadataArray) {
48893
- if (!columnDescriptions) {
48894
- 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
+ });
48895
50507
  }
48896
- const findDescription = (path) => columnDescriptions.find(column => column.path.join("") === path.join(""));
48897
- const mapDescriptionToMetadata = (metadata, path) => {
48898
- var _a;
48899
- const description = findDescription(path);
48900
- if (description) {
48901
- metadata.description = description.description;
48902
- if (((_a = description.bigqueryPolicyTags) === null || _a === void 0 ? void 0 : _a.length) > 0) {
48903
- metadata.policyTags = {
48904
- names: description.bigqueryPolicyTags
48905
- };
48906
- }
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));
48907
50515
  }
48908
- if (metadata.fields) {
48909
- 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
+ }
48910
50539
  }
48911
- return metadata;
48912
- };
48913
- const newMetadata = metadataArray.map(metaItem => mapDescriptionToMetadata(metaItem, [metaItem.name]));
48914
- return newMetadata;
48915
- }
48916
- function createBigQueryError(jobMetadata) {
48917
- const error = new Error(jobMetadata.status.errorResult.message);
48918
- if (jobMetadata.jobReference && jobMetadata.jobReference.jobId) {
48919
- error.metadata = {
48920
- bigquery: {
48921
- 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
+ }
48922
50549
  }
48923
- };
50550
+ }
48924
50551
  }
48925
- return error;
50552
+ return results;
48926
50553
  }
48927
50554
 
48928
50555
  class MySqlPoolExecutor {
@@ -48967,7 +50594,7 @@ class MySqlPoolExecutor {
48967
50594
  await this.pool.end();
48968
50595
  }
48969
50596
  }
48970
- function convertFieldType$1(type) {
50597
+ function convertFieldType(type) {
48971
50598
  switch (String(type).toUpperCase()) {
48972
50599
  case "FLOAT":
48973
50600
  case "DOUBLE":
@@ -49049,7 +50676,7 @@ function defaultClause(col, extra) {
49049
50676
  return ` DEFAULT '${escapeMysqlString(d)}'`;
49050
50677
  }
49051
50678
 
49052
- const INTERNAL_SCHEMAS$1 = new Set([
50679
+ const INTERNAL_SCHEMAS = new Set([
49053
50680
  "information_schema",
49054
50681
  "mysql",
49055
50682
  "performance_schema",
@@ -49194,7 +50821,7 @@ class MySqlDbAdapter {
49194
50821
  const comment = String((_b = (_a = row.column_comment) !== null && _a !== void 0 ? _a : row.COLUMN_COMMENT) !== null && _b !== void 0 ? _b : "");
49195
50822
  return sqlanvil.Field.create({
49196
50823
  name: ((_c = row.column_name) !== null && _c !== void 0 ? _c : row.COLUMN_NAME),
49197
- 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)),
49198
50825
  description: comment || undefined
49199
50826
  });
49200
50827
  })
@@ -49216,7 +50843,7 @@ class MySqlDbAdapter {
49216
50843
  });
49217
50844
  return result.rows
49218
50845
  .map(row => { var _a; return ((_a = row.schema_name) !== null && _a !== void 0 ? _a : row.SCHEMA_NAME); })
49219
- .filter(name => !INTERNAL_SCHEMAS$1.has(name));
50846
+ .filter(name => !INTERNAL_SCHEMAS.has(name));
49220
50847
  }
49221
50848
  async createSchema(_database, schema) {
49222
50849
  await this.execute(`create database if not exists \`${schema}\``, {
@@ -49280,372 +50907,6 @@ class MySqlDbAdapter {
49280
50907
  }
49281
50908
  }
49282
50909
 
49283
- const maybeInitializePg = (() => {
49284
- let initialized = false;
49285
- return () => {
49286
- if (!initialized) {
49287
- initialized = true;
49288
- pg__namespace.types.setTypeParser(20, Number);
49289
- }
49290
- };
49291
- })();
49292
- class PgPoolExecutor {
49293
- constructor(clientConfig, options) {
49294
- maybeInitializePg();
49295
- this.pool = new pg__namespace.Pool(Object.assign(Object.assign({}, clientConfig), { max: options === null || options === void 0 ? void 0 : options.concurrencyLimit }));
49296
- this.pool.on("error", err => {
49297
- console.error("pg.Pool idle client error", err.message, err.stack);
49298
- });
49299
- }
49300
- async verifyConnection() {
49301
- const client = await this.pool.connect();
49302
- try {
49303
- await client.query("select 1");
49304
- }
49305
- finally {
49306
- client.release();
49307
- }
49308
- }
49309
- async withClientLock(callback) {
49310
- const client = await this.pool.connect();
49311
- let released = false;
49312
- const releaseOnce = (err) => {
49313
- if (released) {
49314
- return;
49315
- }
49316
- released = true;
49317
- try {
49318
- client.release(err);
49319
- }
49320
- catch (e) {
49321
- console.error("Error thrown when releasing pg.Client", e.message, e.stack);
49322
- }
49323
- };
49324
- try {
49325
- client.on("error", err => {
49326
- console.error("pg.Client client error", err.message, err.stack);
49327
- releaseOnce(err);
49328
- });
49329
- return await callback({
49330
- execute: async (statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
49331
- return await new Promise((resolve, reject) => {
49332
- var _a;
49333
- const query = client.query(new QueryStream__default["default"](statement, options === null || options === void 0 ? void 0 : options.params));
49334
- const results = new LimitedResultSet({
49335
- rowLimit: options === null || options === void 0 ? void 0 : options.rowLimit,
49336
- byteLimit: options === null || options === void 0 ? void 0 : options.byteLimit
49337
- });
49338
- (_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.")));
49339
- query.on("data", (row) => {
49340
- try {
49341
- verifyUniqueColumnNames(query.cursor._result.fields);
49342
- }
49343
- catch (e) {
49344
- query.destroy(e);
49345
- return;
49346
- }
49347
- if (!results.push(row)) {
49348
- query.cursor.close();
49349
- }
49350
- });
49351
- query.on("error", err => {
49352
- releaseOnce(err);
49353
- reject(err);
49354
- });
49355
- query.on("end", () => {
49356
- resolve(results.rows);
49357
- });
49358
- });
49359
- }
49360
- });
49361
- }
49362
- finally {
49363
- releaseOnce();
49364
- }
49365
- }
49366
- async close() {
49367
- await this.pool.end();
49368
- }
49369
- }
49370
- function verifyUniqueColumnNames(fields) {
49371
- const colNames = new Set();
49372
- fields.forEach(field => {
49373
- if (colNames.has(field.name)) {
49374
- throw new Error(`Ambiguous column name: ${field.name}`);
49375
- }
49376
- colNames.add(field.name);
49377
- });
49378
- }
49379
- function convertFieldType(type) {
49380
- switch (String(type).toUpperCase()) {
49381
- case "FLOAT":
49382
- case "FLOAT4":
49383
- case "FLOAT8":
49384
- case "DOUBLE PRECISION":
49385
- case "REAL":
49386
- return sqlanvil.Field.Primitive.FLOAT;
49387
- case "INTEGER":
49388
- case "INT":
49389
- case "INT2":
49390
- case "INT4":
49391
- case "INT8":
49392
- case "BIGINT":
49393
- case "SMALLINT":
49394
- return sqlanvil.Field.Primitive.INTEGER;
49395
- case "DECIMAL":
49396
- case "NUMERIC":
49397
- return sqlanvil.Field.Primitive.NUMERIC;
49398
- case "BOOLEAN":
49399
- case "BOOL":
49400
- return sqlanvil.Field.Primitive.BOOLEAN;
49401
- case "STRING":
49402
- case "VARCHAR":
49403
- case "CHAR":
49404
- case "CHARACTER":
49405
- case "CHARACTER VARYING":
49406
- case "NVARCHAR":
49407
- case "TEXT":
49408
- case "NCHAR":
49409
- case "BPCHAR":
49410
- return sqlanvil.Field.Primitive.STRING;
49411
- case "DATE":
49412
- return sqlanvil.Field.Primitive.DATE;
49413
- case "TIMESTAMP":
49414
- case "TIMESTAMPZ":
49415
- case "TIMESTAMP WITHOUT TIME ZONE":
49416
- case "TIMESTAMP WITH TIME ZONE":
49417
- return sqlanvil.Field.Primitive.TIMESTAMP;
49418
- default:
49419
- return sqlanvil.Field.Primitive.UNKNOWN;
49420
- }
49421
- }
49422
-
49423
- const INTERNAL_SCHEMAS = new Set(["information_schema", "pg_catalog", "pg_internal", "pg_toast"]);
49424
- class PostgresDbAdapter {
49425
- constructor(queryExecutor) {
49426
- this.queryExecutor = queryExecutor;
49427
- }
49428
- static async create(credentials, options) {
49429
- const sslMode = (credentials.sslMode || "").toLowerCase();
49430
- const sslEnabled = !(options === null || options === void 0 ? void 0 : options.disableSslForTestsOnly) && sslMode !== "disable";
49431
- const clientConfig = {
49432
- host: credentials.host,
49433
- port: credentials.port,
49434
- database: credentials.database,
49435
- user: credentials.user,
49436
- password: credentials.password,
49437
- ssl: sslEnabled
49438
- ? {
49439
- rejectUnauthorized: sslMode === "verify-ca" || sslMode === "verify-full"
49440
- }
49441
- : false
49442
- };
49443
- const queryExecutor = new PgPoolExecutor(clientConfig, options);
49444
- try {
49445
- await queryExecutor.verifyConnection();
49446
- }
49447
- catch (e) {
49448
- await queryExecutor.close().catch(() => undefined);
49449
- throw new ErrorWithCause(`Could not connect to Postgres at ${credentials.host}:${credentials.port} ` +
49450
- `as "${credentials.user}": ${e.message}`, e);
49451
- }
49452
- return new PostgresDbAdapter(queryExecutor);
49453
- }
49454
- async execute(statement, options = { rowLimit: 1000, byteLimit: 1024 * 1024 }) {
49455
- return await this.withClientLock(client => client.execute(statement, options));
49456
- }
49457
- async executeRaw(statement, options = { rowLimit: 1000 }) {
49458
- const result = await this.execute(statement, options);
49459
- return Object.assign(Object.assign({}, result), { schema: [] });
49460
- }
49461
- async withClientLock(callback) {
49462
- return await this.queryExecutor.withClientLock(client => callback({
49463
- execute: async (stmt, opts = { rowLimit: 1000, byteLimit: 1024 * 1024 }) => {
49464
- try {
49465
- const rows = await client.execute(stmt, opts);
49466
- return { rows, metadata: {} };
49467
- }
49468
- catch (e) {
49469
- if (opts.includeQueryInError) {
49470
- throw new Error(`Error encountered while running "${stmt}": ${e.message}`);
49471
- }
49472
- throw new ErrorWithCause(`Error executing postgres query: ${e.message}`, e);
49473
- }
49474
- },
49475
- executeRaw: async (stmt, opts = { rowLimit: 1000 }) => {
49476
- const positional = opts.params ? Object.values(opts.params) : undefined;
49477
- const rows = await client.execute(stmt, { params: positional, rowLimit: opts.rowLimit });
49478
- return { rows, schema: [], metadata: {} };
49479
- }
49480
- }));
49481
- }
49482
- async evaluate(queryOrAction) {
49483
- const validationQueries = collectEvaluationQueries(queryOrAction, false, (query) => !!query ? `explain ${query}` : "").map((validationQuery, index) => ({ index, validationQuery }));
49484
- const validationQueriesWithoutWrappers = collectEvaluationQueries(queryOrAction, false);
49485
- const queryEvaluations = new Array();
49486
- for (const { index, validationQuery } of validationQueries) {
49487
- let evaluationResponse = {
49488
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.SUCCESS
49489
- };
49490
- try {
49491
- await this.execute(validationQuery.query);
49492
- }
49493
- catch (e) {
49494
- evaluationResponse = {
49495
- status: sqlanvil.QueryEvaluation.QueryEvaluationStatus.FAILURE,
49496
- error: parsePostgresEvalError(validationQuery.query, e)
49497
- };
49498
- }
49499
- queryEvaluations.push(sqlanvil.QueryEvaluation.create(Object.assign(Object.assign({}, evaluationResponse), { incremental: validationQuery.incremental, query: validationQueriesWithoutWrappers[index].query })));
49500
- }
49501
- return queryEvaluations;
49502
- }
49503
- async tables(_database, schema) {
49504
- const params = [];
49505
- let schemaClause = "";
49506
- let matviewSchemaClause = "";
49507
- if (schema) {
49508
- schemaClause = "and table_schema = $1";
49509
- matviewSchemaClause = "and schemaname = $1";
49510
- params.push(schema);
49511
- }
49512
- const queryResult = await this.execute(`select table_name, table_schema
49513
- from information_schema.tables
49514
- where table_schema not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
49515
- ${schemaClause}
49516
- union
49517
- select matviewname as table_name, schemaname as table_schema
49518
- from pg_matviews
49519
- where schemaname not in ('information_schema', 'pg_catalog', 'pg_internal', 'pg_toast')
49520
- ${matviewSchemaClause}`, { params, rowLimit: 10000, includeQueryInError: true });
49521
- const targets = queryResult.rows.map(row => ({
49522
- schema: row.table_schema,
49523
- name: row.table_name
49524
- }));
49525
- return await Promise.all(targets.map(target => this.table(target)));
49526
- }
49527
- async search(searchText, options = { limit: 1000 }) {
49528
- const results = await this.execute(`select tables.table_schema as table_schema, tables.table_name as table_name
49529
- from information_schema.tables as tables
49530
- left join information_schema.columns columns
49531
- on tables.table_schema = columns.table_schema
49532
- and tables.table_name = columns.table_name
49533
- where tables.table_schema ilike $1
49534
- or tables.table_name ilike $1
49535
- or columns.column_name ilike $1
49536
- group by 1, 2`, {
49537
- params: [`%${searchText}%`],
49538
- rowLimit: options.limit
49539
- });
49540
- return await Promise.all(results.rows.map(row => this.table({
49541
- schema: row.table_schema,
49542
- name: row.table_name
49543
- })));
49544
- }
49545
- async table(target) {
49546
- const params = [target.schema, target.name];
49547
- const [tableResults, columnResults, descriptionResults, matviewResults, matviewColumns] = await Promise.all([
49548
- this.execute(`select table_type from information_schema.tables where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49549
- this.execute(`select column_name, data_type, is_nullable, ordinal_position
49550
- from information_schema.columns
49551
- where table_schema = $1 and table_name = $2`, { params, includeQueryInError: true }),
49552
- this.execute(`select objsubid as column_number, description
49553
- from pg_description
49554
- where objoid = (
49555
- select oid from pg_class where relname = $2 and relnamespace = (
49556
- select oid from pg_namespace where nspname = $1
49557
- )
49558
- )`, { params, includeQueryInError: true }),
49559
- this.execute(`select 1 from pg_matviews where schemaname = $1 and matviewname = $2`, { params, includeQueryInError: true }),
49560
- this.execute(`select a.attname as column_name, format_type(a.atttypid, a.atttypmod) as data_type,
49561
- a.attnum as ordinal_position
49562
- from pg_attribute a
49563
- join pg_class c on c.oid = a.attrelid
49564
- join pg_namespace n on n.oid = c.relnamespace
49565
- where n.nspname = $1 and c.relname = $2 and a.attnum > 0 and not a.attisdropped
49566
- order by a.attnum`, { params, includeQueryInError: true })
49567
- ]);
49568
- const findDescription = (columnNumber) => { var _a; return (_a = descriptionResults.rows.find(row => row.column_number === columnNumber)) === null || _a === void 0 ? void 0 : _a.description; };
49569
- if (tableResults.rows.length > 0) {
49570
- return sqlanvil.TableMetadata.create({
49571
- target,
49572
- type: tableResults.rows[0].table_type === "VIEW"
49573
- ? sqlanvil.TableMetadata.Type.VIEW
49574
- : sqlanvil.TableMetadata.Type.TABLE,
49575
- fields: columnResults.rows.map(row => sqlanvil.Field.create({
49576
- name: row.column_name,
49577
- primitive: convertFieldType(row.data_type),
49578
- description: findDescription(row.ordinal_position)
49579
- })),
49580
- description: findDescription(0)
49581
- });
49582
- }
49583
- if (matviewResults.rows.length > 0) {
49584
- return sqlanvil.TableMetadata.create({
49585
- target,
49586
- type: sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW,
49587
- fields: matviewColumns.rows.map(row => sqlanvil.Field.create({
49588
- name: row.column_name,
49589
- primitive: convertFieldType(String(row.data_type).replace(/\(.*\)/, "")),
49590
- description: findDescription(row.ordinal_position)
49591
- })),
49592
- description: findDescription(0)
49593
- });
49594
- }
49595
- return null;
49596
- }
49597
- async deleteTable(target) {
49598
- const metadata = await this.table(target);
49599
- if (!metadata) {
49600
- return;
49601
- }
49602
- const kind = metadata.type === sqlanvil.TableMetadata.Type.VIEW ? "view" : "table";
49603
- await this.execute(`drop ${kind} if exists "${target.schema}"."${target.name}" cascade`, { includeQueryInError: true });
49604
- }
49605
- async schemas(_database) {
49606
- const result = await this.execute(`select nspname from pg_namespace`, {
49607
- includeQueryInError: true
49608
- });
49609
- return result.rows
49610
- .map(row => row.nspname)
49611
- .filter(name => !INTERNAL_SCHEMAS.has(name) && !name.startsWith("pg_"));
49612
- }
49613
- async createSchema(_database, schema) {
49614
- await this.execute(`create schema if not exists "${schema}"`, {
49615
- includeQueryInError: true
49616
- });
49617
- }
49618
- async setMetadata(action) {
49619
- var _a;
49620
- const { target, actionDescriptor, tableType } = action;
49621
- const actualMetadata = await this.table(target);
49622
- if (!actualMetadata) {
49623
- return;
49624
- }
49625
- const relationKind = actualMetadata.type === sqlanvil.TableMetadata.Type.MATERIALIZED_VIEW
49626
- ? "materialized view"
49627
- : tableType === "view"
49628
- ? "view"
49629
- : "table";
49630
- const queries = [];
49631
- if (actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.description) {
49632
- queries.push(this.execute(`comment on ${relationKind} "${target.schema}"."${target.name}" is '${actionDescriptor.description.replace(/'/g, "''")}'`));
49633
- }
49634
- if (((_a = actionDescriptor === null || actionDescriptor === void 0 ? void 0 : actionDescriptor.columns) === null || _a === void 0 ? void 0 : _a.length) > 0) {
49635
- actionDescriptor.columns
49636
- .filter(column => column.path.length === 1 &&
49637
- actualMetadata.fields.some(field => field.name === column.path[0]))
49638
- .forEach(column => {
49639
- queries.push(this.execute(`comment on column "${target.schema}"."${target.name}"."${column.path[0]}" is '${column.description.replace(/'/g, "''")}'`));
49640
- });
49641
- }
49642
- await Promise.all(queries);
49643
- }
49644
- async close() {
49645
- await this.queryExecutor.close();
49646
- }
49647
- }
49648
-
49649
50910
  class SupabaseDbAdapter extends PostgresDbAdapter {
49650
50911
  static async create(credentials, options) {
49651
50912
  const sslMode = (credentials.sslMode || "").toLowerCase();