@itwin/core-backend 5.12.0-dev.15 → 5.12.0-dev.16

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ECDb.d.ts","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ECDb.d.ts","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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"}
package/lib/cjs/ECDb.js CHANGED
@@ -464,10 +464,15 @@ class ECDb {
464
464
  withQueryReader(ecsql, callback, params, config) {
465
465
  if (!this[Symbols_1._nativeDb].isOpen())
466
466
  throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR_NOTOPEN, "db not open");
467
- const executor = new ECSqlRowExecutor_1.ECSqlRowExecutor(this);
468
- const reader = new ECSqlSyncReader_1.ECSqlSyncReader(executor, ecsql, params, config);
469
- const release = () => executor[Symbol.dispose]();
467
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
468
+ const stmt = this._statementCache.findAndRemove(ecsql) ?? new ECSqlStatement_1.ECSqlStatement();
469
+ const executor = new ECSqlRowExecutor_1.ECSqlRowExecutor(this, stmt, loggerCategory);
470
+ const release = () => {
471
+ executor[Symbol.dispose]();
472
+ (0, ECSqlRowExecutor_1.releaseECSqlStatement)(stmt, this._statementCache, loggerCategory, executor.canCacheStatement);
473
+ };
470
474
  try {
475
+ const reader = new ECSqlSyncReader_1.ECSqlSyncReader(executor, ecsql, params, config);
471
476
  const val = callback(reader);
472
477
  if (val instanceof Promise) {
473
478
  val.then(release, release);
@@ -1 +1 @@
1
- {"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F;;GAEG;AACH,sDAAkF;AAElF,oDAAwH;AACxH,mEAAgE;AAChE,uDAAoD;AACpD,qDAAuE;AACvE,8DAAyD;AACzD,uDAAoE;AACpE,gDAA+C;AAC/C,yDAAsD;AACtD,uDAA6E;AAE7E,MAAM,cAAc,GAAW,6CAAqB,CAAC,IAAI,CAAC;AAE1D;;GAEG;AACH,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,uDAAQ,CAAA;IACR,yDAAS,CAAA;IACT,sGAAsG;IACtG,6DAAW,CAAA;AACb,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AAED;;GAEG;AACH,MAAa,IAAI;IACP,SAAS,CAAuB;IACxC,4DAA4D;IAC3C,eAAe,GAAG,IAAI,gCAAc,EAAkB,CAAC;IAChE,qBAAqB,GAAG,IAAI,gCAAc,EAAmB,CAAC;IAEtE,wDAAwD;IACxC,aAAa,GAAG,IAAI,sBAAO,EAAc,CAAC;IAE1D;;OAEG;IACI,gBAAgB,CAAC,IAAY;QAClC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,qBAAqB,GAAG,IAAI,gCAAc,CAAkB,IAAI,CAAC,CAAC;IACzE,CAAC;IAED;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,6BAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IACD;;OAEG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS;YACjB,OAAO;QAET,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IACD;;;;;OAKG;IACI,QAAQ,CAAC,QAAgB,EAAE,KAAa;QAC7C,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,gBAAgB,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACvJ,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,mBAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD;;;;OAIG;IACI,QAAQ,CAAC,KAAa;QAC3B,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,gBAAgB,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACvJ,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,mBAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,iGAAiG;IAC1F,OAAO;QACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,QAAQ,CAAC,QAAgB;QAC9B,MAAM,MAAM,GAAa,IAAI,CAAC,mBAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,MAAM,KAAK,uBAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,yBAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAgB,EAAE,WAAyB,YAAY,CAAC,QAAQ;QAC5E,MAAM,cAAc,GAAa,QAAQ,KAAK,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAQ,CAAC,SAAS,CAAC;QAC7G,MAAM,UAAU,GAAY,QAAQ,KAAK,YAAY,CAAC,WAAW,CAAC;QAClE,MAAM,MAAM,GAAa,IAAI,CAAC,mBAAS,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACtF,IAAI,MAAM,KAAK,uBAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,yBAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACzD,CAAC;IAED,uCAAuC;IACvC,IAAW,MAAM,KAAc,OAAO,IAAI,CAAC,mBAAS,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEjE;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,mBAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED;;MAEE;IACK,WAAW;QAChB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,mBAAS,CAAC,CAAC,cAAc,EAAE,CAAC;IACnC,CAAC;IAED,8CAA8C;IACvC,mBAAmB;QACxB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,8CAA8C;IACvC,uBAAuB;QAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,aAAsB;QACvC,MAAM,MAAM,GAAa,IAAI,CAAC,mBAAS,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QACpE,IAAI,MAAM,KAAK,uBAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,yBAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACI,cAAc;QACnB,MAAM,MAAM,GAAa,IAAI,CAAC,mBAAS,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1D,IAAI,MAAM,KAAK,uBAAQ,CAAC,YAAY;YAClC,MAAM,IAAI,yBAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACI,YAAY,CAAC,QAAgB;QAClC,MAAM,MAAM,GAAa,IAAI,CAAC,mBAAS,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,MAAM,KAAK,uBAAQ,CAAC,YAAY,EAAE,CAAC;YACrC,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,iCAAiC,QAAQ,IAAI,CAAC,CAAC;YAC/E,MAAM,IAAI,yBAAW,CAAC,MAAM,EAAE,iCAAiC,QAAQ,IAAI,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACI,WAAW,CAAC,WAAqB;QACtC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAC1B,OAAO;QACT,IAAI,IAAI,CAAC,mBAAS,CAAC,CAAC,iBAAiB,EAAE;YACrC,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,eAAe,EAAE,iDAAiD,CAAC,CAAC;QAErG,IAAI,CAAC;YACH,IAAI,CAAC,mBAAS,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;YACzC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,qBAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,2BAA2B,KAAK,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,eAAe,EAAE,2BAA2B,KAAK,EAAE,CAAC,CAAC;QACtF,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,cAAc,CAAC,IAAY;QAChC,OAAO,IAAI,CAAC,mBAAS,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,wBAAwB,CAAI,KAAa,EAAE,QAA0C,EAAE,SAAS,GAAG,IAAI;QAC5G,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,oCAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACI,kBAAkB,CAAI,KAAa,EAAE,QAA0C,EAAE,SAAS,GAAG,IAAI;QACtG,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;MAKE;IACK,qBAAqB,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI;QAC1D,4DAA4D;QAC5D,OAAO,IAAI,oCAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,4DAA4D;IACrD,qBAAqB,CAAI,KAAa,EAAE,QAAqC,EAAE,SAAS,GAAG,IAAI;QACpG,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,4DAA4D;IACrD,aAAa,CAAI,KAAa,EAAE,QAAqC,EAAE,SAAS,GAAG,IAAI;QAC5F,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,4DAA4D;IACrD,gBAAgB,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI;QACrD,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,+BAAc,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,2BAA2B,CAAI,GAAW,EAAE,QAAsC,EAAE,SAAS,GAAG,IAAI;QACzG,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1G,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACpE,IAAI,CAAC;YACH,MAAM,GAAG,GAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACI,mBAAmB,CAAI,GAAW,EAAE,QAAsC,EAAE,SAAS,GAAG,IAAI;QACjG,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,sBAAsB,CAAC,GAAW,EAAE,SAAS,GAAG,IAAI;QACzD,MAAM,IAAI,GAAG,IAAI,iCAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAS,CAAC,EAAE,SAAS,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gBAAgB;IAChB,IAAW,CAAC,mBAAS,CAAC;QACpB,IAAA,qBAAM,EAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;SAWK;IACE,iBAAiB,CAAC,KAAa,EAAE,MAAoB,EAAE,MAAqB;QACjF,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,QAAQ,GAAG;YACf,OAAO,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;gBACzC,OAAO,iCAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAS,CAAC,EAAE,OAAO,CAAC,CAAC;YACvE,CAAC;SACF,CAAC;QACF,OAAO,IAAI,yBAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;;SAaK;IACE,eAAe,CAAI,KAAa,EAAE,QAAwC,EAAE,MAAoB,EAAE,MAAgC;QACvI,IAAI,CAAC,IAAI,CAAC,mBAAS,CAAC,CAAC,MAAM,EAAE;YAC3B,MAAM,IAAI,yBAAW,CAAC,uBAAQ,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC;QAEzE,MAAM,QAAQ,GAAG,IAAI,mCAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,iCAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF;AAjdD,oBAidC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module ECDb\n */\nimport { assert, BeEvent, DbResult, Logger, OpenMode } from \"@itwin/core-bentley\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { DbQueryRequest, ECSchemaProps, ECSqlReader, IModelError, QueryBinder, QueryOptions } from \"@itwin/core-common\";\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\nimport { ECSqlStatement, ECSqlWriteStatement } from \"./ECSqlStatement\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport { ECSqlRowExecutor } from \"./ECSqlRowExecutor\";\nimport { ECSqlSyncReader, SynchronousQueryOptions } from \"./ECSqlSyncReader\";\n\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\n\n/** Modes for how to open [ECDb]($backend) files.\n * @public\n */\nexport enum ECDbOpenMode {\n Readonly,\n ReadWrite,\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\n FileUpgrade,\n}\n\n/** An ECDb file\n * @public\n */\nexport class ECDb implements Disposable {\n private _nativeDb?: IModelJsNative.ECDb;\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\n\n /** Event called when the ECDb is about to be closed. */\n public readonly onBeforeClose = new BeEvent<() => void>();\n\n /** only for tests\n * @internal\n */\n public resetSqliteCache(size: number) {\n this._sqliteStatementCache.clear();\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\n }\n\n constructor() {\n this._nativeDb = new IModelNative.platform.ECDb();\n }\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\n * ECDb object.\n */\n public [Symbol.dispose](): void {\n if (!this._nativeDb)\n return;\n\n this.closeDb();\n this._nativeDb.dispose();\n this._nativeDb = undefined;\n }\n /**\n * Attach an iModel file to this connection and load and register its schemas.\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\n * @param fileName IModel file name\n * @param alias identifier for the attached file. This identifer is used to access schema from the attached file. e.g. if alias is 'abc' then schema can be accessed using 'abc.MySchema.MyClass'\n */\n public attachDb(fileName: string, alias: string): void {\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\n }\n this[_nativeDb].attachDb(fileName, alias);\n }\n /**\n * Detach the attached file from this connection. The attached file is closed and its schemas are unregistered.\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\n * @param alias identifer that was used in the call to [[attachDb]]\n */\n public detachDb(alias: string): void {\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\n }\n this.clearCaches();\n this[_nativeDb].detachDb(alias);\n }\n\n /** @deprecated in 5.0 - might be removed in next major version. Use [Symbol.dispose] instead. */\n public dispose(): void {\n this[Symbol.dispose]();\n }\n\n /** Create an ECDb\n * @param pathName The path to the ECDb file to create.\n * @throws [IModelError]($common) if the operation failed.\n */\n public createDb(pathName: string): void {\n const status: DbResult = this[_nativeDb].createDb(pathName);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to created ECDb\");\n }\n\n /** Open the ECDb.\n * @param pathName The path to the ECDb file to open\n * @param openMode Open mode\n * @throws [IModelError]($common) if the operation failed.\n */\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\n const status: DbResult = this[_nativeDb].openDb(pathName, nativeOpenMode, tryUpgrade);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to open ECDb\");\n }\n\n /** Returns true if the ECDb is open */\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\n\n /** Close the Db after saving any uncommitted changes.\n * @throws [IModelError]($common) if the database is not open.\n */\n public closeDb(): void {\n this.onBeforeClose.raiseEvent();\n this.clearCaches();\n this[_nativeDb].closeDb();\n }\n\n /** Clear all in-memory caches held in this ECDb.\n * @beta\n */\n public clearCaches(): void {\n this._statementCache.clear();\n this._sqliteStatementCache.clear();\n this[_nativeDb].clearECDbCache();\n }\n\n /** @internal use to test statement caching */\n public clearStatementCache() {\n this._statementCache.clear();\n }\n\n /** @internal use to test statement caching */\n public getCachedStatementCount() {\n return this._statementCache.size;\n }\n\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\n * @param changesetName The name of the operation that generated these changes.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public saveChanges(changesetName?: string): void {\n const status: DbResult = this[_nativeDb].saveChanges(changesetName);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to save changes\");\n }\n\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public abandonChanges(): void {\n const status: DbResult = this[_nativeDb].abandonChanges();\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to abandon changes\");\n }\n\n /** Import a schema.\n *\n * If the import was successful, the database is automatically saved to disk.\n * @param pathName Path to ECSchema XML file to import.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public importSchema(pathName: string): void {\n const status: DbResult = this[_nativeDb].importSchema(pathName);\n if (status !== DbResult.BE_SQLITE_OK) {\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\n }\n this.clearCaches();\n }\n\n /** Removes unused schemas from the database.\n *\n * If the removal was successful, the database is automatically saved to disk.\n * @param schemaNames Array of schema names to drop\n * @throws [IModelError]($common) if the database if the operation failed.\n * @alpha\n */\n public dropSchemas(schemaNames: string[]): void {\n if (schemaNames.length === 0)\n return;\n if (this[_nativeDb].schemaSyncEnabled())\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot drop schemas when schema sync is enabled\");\n\n try {\n this[_nativeDb].dropSchemas(schemaNames);\n this.saveChanges('dropped unused schemas');\n } catch (error: any) {\n Logger.logError(loggerCategory, `Failed to drop schemas: ${error}`);\n this.abandonChanges();\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Failed to drop schemas: ${error}`);\n } finally {\n this.clearCaches();\n }\n }\n\n /**\n * Returns the full schema for the input name.\n * @param name The name of the schema e.g. 'ECDbMeta'\n * @returns The SchemaProps for the requested schema\n * @throws if the schema can not be found or loaded.\n */\n public getSchemaProps(name: string): ECSchemaProps {\n return this[_nativeDb].getSchemaProps(name);\n }\n\n /**\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withWriteStatement]]\n * @beta\n */\n public withCachedWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\n const release = () => this._statementCache.addOrDispose(stmt);\n try {\n const val = callback(new ECSqlWriteStatement(stmt));\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withCachedWriteStatement]]\n * @beta\n */\n public withWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\n const stmt = this.prepareWriteStatement(ecsql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an ECSQL statement.\n * @param ecsql The ECSQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @beta\n */\n public prepareWriteStatement(ecsql: string, logErrors = true): ECSqlWriteStatement {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n return new ECSqlWriteStatement(this.prepareStatement(ecsql, logErrors));\n }\n\n /**\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withStatement]]\n * @public\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withCachedWriteStatement]] for INSERT/UPDATE/DELETE instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\n const release = () => this._statementCache.addOrDispose(stmt);\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withPreparedStatement]]\n * @public\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withWriteStatement]] for INSERT/UPDATE/DELETE instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this.prepareStatement(ecsql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an ECSQL statement.\n * @param ecsql The ECSQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @deprecated in 4.11 - might be removed in next major version. Use [[prepareWriteStatement]] when preparing an INSERT/UPDATE/DELETE statement or [[createQueryReader]] to execute a SELECT statement.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = new ECSqlStatement();\n stmt.prepare(this[_nativeDb], ecsql, logErrors);\n return stmt;\n }\n\n /**\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withPreparedStatement]]\n * @public\n */\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\n try {\n const val: T = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on a SQL statement. After the callback completes the statement is disposed.\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @public\n */\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\n const stmt = this.prepareSqliteStatement(sql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val: T = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an SQL statement.\n * @param sql The SQLite SQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @internal\n */\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\n const stmt = new SqliteStatement(sql);\n stmt.prepare(this[_nativeDb], logErrors);\n return stmt;\n }\n\n /** @internal */\n public get [_nativeDb](): IModelJsNative.ECDb {\n assert(undefined !== this._nativeDb);\n return this._nativeDb;\n }\n\n /** Allow to execute query and read results along with meta data. The result are streamed.\n *\n * See also:\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\n *\n * @param params The values to bind to the parameters (if the ECSQL has any).\n * @param config Allow to specify certain flags which control how query is executed.\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\n * @public\n * */\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\n }\n const executor = {\n execute: async (request: DbQueryRequest) => {\n return ConcurrentQuery.executeQueryRequest(this[_nativeDb], request);\n },\n };\n return new ECSqlReader(executor, ecsql, params, config);\n }\n\n /** Allow to execute query and read results along with meta data. The result are stepped one by one.\n *\n * See also:\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\n * @param ecsql The ECSQL query to execute.\n * @param callback the callback to invoke on the prepared ECSqlSyncReader\n * @param params The values to bind to the parameters (if the ECSQL has any).\n * @param config Optional flags which control how query is executed.\n * @returns the value returned by `callback`.\n * @throws IModelError if db is not open or if error occurs during statement execution\n * @beta\n * */\n public withQueryReader<T>(ecsql: string, callback: (reader: ECSqlSyncReader) => T, params?: QueryBinder, config?: SynchronousQueryOptions): T {\n if (!this[_nativeDb].isOpen())\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\n\n const executor = new ECSqlRowExecutor(this);\n const reader = new ECSqlSyncReader(executor, ecsql, params, config);\n const release = () => executor[Symbol.dispose]();\n try {\n const val = callback(reader);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err: any) {\n release();\n throw err;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ECDb.js","sourceRoot":"","sources":["../../src/ECDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module ECDb\n */\nimport { assert, BeEvent, DbResult, Logger, OpenMode } from \"@itwin/core-bentley\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { DbQueryRequest, ECSchemaProps, ECSqlReader, IModelError, QueryBinder, QueryOptions } from \"@itwin/core-common\";\nimport { BackendLoggerCategory } from \"./BackendLoggerCategory\";\nimport { ConcurrentQuery } from \"./ConcurrentQuery\";\nimport { ECSqlStatement, ECSqlWriteStatement } from \"./ECSqlStatement\";\nimport { IModelNative } from \"./internal/NativePlatform\";\nimport { SqliteStatement, StatementCache } from \"./SqliteStatement\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport { ECSqlRowExecutor, releaseECSqlStatement } from \"./ECSqlRowExecutor\";\nimport { ECSqlSyncReader, SynchronousQueryOptions } from \"./ECSqlSyncReader\";\n\nconst loggerCategory: string = BackendLoggerCategory.ECDb;\n\n/** Modes for how to open [ECDb]($backend) files.\n * @public\n */\nexport enum ECDbOpenMode {\n Readonly,\n ReadWrite,\n /** Opens the file read-write and upgrades the file if necessary to the latest file format version. */\n FileUpgrade,\n}\n\n/** An ECDb file\n * @public\n */\nexport class ECDb implements Disposable {\n private _nativeDb?: IModelJsNative.ECDb;\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private readonly _statementCache = new StatementCache<ECSqlStatement>();\n private _sqliteStatementCache = new StatementCache<SqliteStatement>();\n\n /** Event called when the ECDb is about to be closed. */\n public readonly onBeforeClose = new BeEvent<() => void>();\n\n /** only for tests\n * @internal\n */\n public resetSqliteCache(size: number) {\n this._sqliteStatementCache.clear();\n this._sqliteStatementCache = new StatementCache<SqliteStatement>(size);\n }\n\n constructor() {\n this._nativeDb = new IModelNative.platform.ECDb();\n }\n /** Call this function when finished with this ECDb object. This releases the native resources held by the\n * ECDb object.\n */\n public [Symbol.dispose](): void {\n if (!this._nativeDb)\n return;\n\n this.closeDb();\n this._nativeDb.dispose();\n this._nativeDb = undefined;\n }\n /**\n * Attach an iModel file to this connection and load and register its schemas.\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\n * @param fileName IModel file name\n * @param alias identifier for the attached file. This identifer is used to access schema from the attached file. e.g. if alias is 'abc' then schema can be accessed using 'abc.MySchema.MyClass'\n */\n public attachDb(fileName: string, alias: string): void {\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\n }\n this[_nativeDb].attachDb(fileName, alias);\n }\n /**\n * Detach the attached file from this connection. The attached file is closed and its schemas are unregistered.\n * @note There are some reserve tablespace names that cannot be used. They are 'main', 'schema_sync_db', 'ecchange' & 'temp'\n * @param alias identifer that was used in the call to [[attachDb]]\n */\n public detachDb(alias: string): void {\n if (alias.toLowerCase() === \"main\" || alias.toLowerCase() === \"schema_sync_db\" || alias.toLowerCase() === \"ecchange\" || alias.toLowerCase() === \"temp\") {\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Reserved tablespace name cannot be used\");\n }\n this.clearCaches();\n this[_nativeDb].detachDb(alias);\n }\n\n /** @deprecated in 5.0 - might be removed in next major version. Use [Symbol.dispose] instead. */\n public dispose(): void {\n this[Symbol.dispose]();\n }\n\n /** Create an ECDb\n * @param pathName The path to the ECDb file to create.\n * @throws [IModelError]($common) if the operation failed.\n */\n public createDb(pathName: string): void {\n const status: DbResult = this[_nativeDb].createDb(pathName);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to created ECDb\");\n }\n\n /** Open the ECDb.\n * @param pathName The path to the ECDb file to open\n * @param openMode Open mode\n * @throws [IModelError]($common) if the operation failed.\n */\n public openDb(pathName: string, openMode: ECDbOpenMode = ECDbOpenMode.Readonly): void {\n const nativeOpenMode: OpenMode = openMode === ECDbOpenMode.Readonly ? OpenMode.Readonly : OpenMode.ReadWrite;\n const tryUpgrade: boolean = openMode === ECDbOpenMode.FileUpgrade;\n const status: DbResult = this[_nativeDb].openDb(pathName, nativeOpenMode, tryUpgrade);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to open ECDb\");\n }\n\n /** Returns true if the ECDb is open */\n public get isOpen(): boolean { return this[_nativeDb].isOpen(); }\n\n /** Close the Db after saving any uncommitted changes.\n * @throws [IModelError]($common) if the database is not open.\n */\n public closeDb(): void {\n this.onBeforeClose.raiseEvent();\n this.clearCaches();\n this[_nativeDb].closeDb();\n }\n\n /** Clear all in-memory caches held in this ECDb.\n * @beta\n */\n public clearCaches(): void {\n this._statementCache.clear();\n this._sqliteStatementCache.clear();\n this[_nativeDb].clearECDbCache();\n }\n\n /** @internal use to test statement caching */\n public clearStatementCache() {\n this._statementCache.clear();\n }\n\n /** @internal use to test statement caching */\n public getCachedStatementCount() {\n return this._statementCache.size;\n }\n\n /** Commit the outermost transaction, writing changes to the file. Then, restart the transaction.\n * @param changesetName The name of the operation that generated these changes.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public saveChanges(changesetName?: string): void {\n const status: DbResult = this[_nativeDb].saveChanges(changesetName);\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to save changes\");\n }\n\n /** Abandon (cancel) the outermost transaction, discarding all changes since last save. Then, restart the transaction.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public abandonChanges(): void {\n const status: DbResult = this[_nativeDb].abandonChanges();\n if (status !== DbResult.BE_SQLITE_OK)\n throw new IModelError(status, \"Failed to abandon changes\");\n }\n\n /** Import a schema.\n *\n * If the import was successful, the database is automatically saved to disk.\n * @param pathName Path to ECSchema XML file to import.\n * @throws [IModelError]($common) if the database is not open or if the operation failed.\n */\n public importSchema(pathName: string): void {\n const status: DbResult = this[_nativeDb].importSchema(pathName);\n if (status !== DbResult.BE_SQLITE_OK) {\n Logger.logError(loggerCategory, `Failed to import schema from '${pathName}'.`);\n throw new IModelError(status, `Failed to import schema from '${pathName}'.`);\n }\n this.clearCaches();\n }\n\n /** Removes unused schemas from the database.\n *\n * If the removal was successful, the database is automatically saved to disk.\n * @param schemaNames Array of schema names to drop\n * @throws [IModelError]($common) if the database if the operation failed.\n * @alpha\n */\n public dropSchemas(schemaNames: string[]): void {\n if (schemaNames.length === 0)\n return;\n if (this[_nativeDb].schemaSyncEnabled())\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Cannot drop schemas when schema sync is enabled\");\n\n try {\n this[_nativeDb].dropSchemas(schemaNames);\n this.saveChanges('dropped unused schemas');\n } catch (error: any) {\n Logger.logError(loggerCategory, `Failed to drop schemas: ${error}`);\n this.abandonChanges();\n throw new IModelError(DbResult.BE_SQLITE_ERROR, `Failed to drop schemas: ${error}`);\n } finally {\n this.clearCaches();\n }\n }\n\n /**\n * Returns the full schema for the input name.\n * @param name The name of the schema e.g. 'ECDbMeta'\n * @returns The SchemaProps for the requested schema\n * @throws if the schema can not be found or loaded.\n */\n public getSchemaProps(name: string): ECSchemaProps {\n return this[_nativeDb].getSchemaProps(name);\n }\n\n /**\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withWriteStatement]]\n * @beta\n */\n public withCachedWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\n const release = () => this._statementCache.addOrDispose(stmt);\n try {\n const val = callback(new ECSqlWriteStatement(stmt));\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withCachedWriteStatement]]\n * @beta\n */\n public withWriteStatement<T>(ecsql: string, callback: (stmt: ECSqlWriteStatement) => T, logErrors = true): T {\n const stmt = this.prepareWriteStatement(ecsql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an ECSQL statement.\n * @param ecsql The ECSQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @beta\n */\n public prepareWriteStatement(ecsql: string, logErrors = true): ECSqlWriteStatement {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n return new ECSqlWriteStatement(this.prepareStatement(ecsql, logErrors));\n }\n\n /**\n * Use a prepared ECSQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for ECSQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withStatement]]\n * @public\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withCachedWriteStatement]] for INSERT/UPDATE/DELETE instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public withPreparedStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this._statementCache.findAndRemove(ecsql) ?? this.prepareStatement(ecsql, logErrors);\n const release = () => this._statementCache.addOrDispose(stmt);\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on an ECSQL statement. After the callback completes the statement is disposed.\n * Use this method for ECSQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withPreparedStatement]]\n * @public\n * @deprecated in 4.11 - might be removed in next major version. Use [[createQueryReader]] for SELECT statements and [[withWriteStatement]] for INSERT/UPDATE/DELETE instead.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public withStatement<T>(ecsql: string, callback: (stmt: ECSqlStatement) => T, logErrors = true): T {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this.prepareStatement(ecsql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an ECSQL statement.\n * @param ecsql The ECSQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @deprecated in 4.11 - might be removed in next major version. Use [[prepareWriteStatement]] when preparing an INSERT/UPDATE/DELETE statement or [[createQueryReader]] to execute a SELECT statement.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public prepareStatement(ecsql: string, logErrors = true): ECSqlStatement {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = new ECSqlStatement();\n stmt.prepare(this[_nativeDb], ecsql, logErrors);\n return stmt;\n }\n\n /**\n * Use a prepared SQL statement, potentially from the statement cache. If the requested statement doesn't exist\n * in the statement cache, a new statement is prepared. After the callback completes, the statement is reset and saved\n * in the statement cache so it can be reused in the future. Use this method for SQL statements that will be\n * reused often and are expensive to prepare. The statement cache holds the most recently used statements, discarding\n * the oldest statements as it fills. For statements you don't intend to reuse, instead use [[withSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @see [[withPreparedStatement]]\n * @public\n */\n public withPreparedSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\n const stmt = this._sqliteStatementCache.findAndRemove(sql) ?? this.prepareSqliteStatement(sql, logErrors);\n const release = () => this._sqliteStatementCache.addOrDispose(stmt);\n try {\n const val: T = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /**\n * Prepared and execute a callback on a SQL statement. After the callback completes the statement is disposed.\n * Use this method for SQL statements are either not expected to be reused, or are not expensive to prepare.\n * For statements that will be reused often, instead use [[withPreparedSqliteStatement]].\n * @param sql The SQLite SQL statement to execute\n * @param callback the callback to invoke on the prepared statement\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @returns the value returned by `callback`.\n * @public\n */\n public withSqliteStatement<T>(sql: string, callback: (stmt: SqliteStatement) => T, logErrors = true): T {\n const stmt = this.prepareSqliteStatement(sql, logErrors);\n const release = () => stmt[Symbol.dispose]();\n try {\n const val: T = callback(stmt);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err) {\n release();\n throw err;\n }\n }\n\n /** Prepare an SQL statement.\n * @param sql The SQLite SQL statement to prepare\n * @param logErrors Determines if error will be logged if statement fail to prepare\n * @throws [IModelError]($common) if there is a problem preparing the statement.\n * @internal\n */\n public prepareSqliteStatement(sql: string, logErrors = true): SqliteStatement {\n const stmt = new SqliteStatement(sql);\n stmt.prepare(this[_nativeDb], logErrors);\n return stmt;\n }\n\n /** @internal */\n public get [_nativeDb](): IModelJsNative.ECDb {\n assert(undefined !== this._nativeDb);\n return this._nativeDb;\n }\n\n /** Allow to execute query and read results along with meta data. The result are streamed.\n *\n * See also:\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\n *\n * @param params The values to bind to the parameters (if the ECSQL has any).\n * @param config Allow to specify certain flags which control how query is executed.\n * @returns Returns an [ECSqlReader]($common) which helps iterate over the result set and also give access to metadata.\n * @public\n * */\n public createQueryReader(ecsql: string, params?: QueryBinder, config?: QueryOptions): ECSqlReader {\n if (!this._nativeDb || !this._nativeDb.isOpen()) {\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\n }\n const executor = {\n execute: async (request: DbQueryRequest) => {\n return ConcurrentQuery.executeQueryRequest(this[_nativeDb], request);\n },\n };\n return new ECSqlReader(executor, ecsql, params, config);\n }\n\n /** Allow to execute query and read results along with meta data. The result are stepped one by one.\n *\n * See also:\n * - [ECSQL Overview]($docs/learning/backend/ExecutingECSQL)\n * - [Code Examples]($docs/learning/backend/ECSQLCodeExamples)\n * - [ECSQL Row Format]($docs/learning/ECSQLRowFormat)\n * @param ecsql The ECSQL query to execute.\n * @param callback the callback to invoke on the prepared ECSqlSyncReader\n * @param params The values to bind to the parameters (if the ECSQL has any).\n * @param config Optional flags which control how query is executed.\n * @returns the value returned by `callback`.\n * @throws IModelError if db is not open or if error occurs during statement execution\n * @beta\n * */\n public withQueryReader<T>(ecsql: string, callback: (reader: ECSqlSyncReader) => T, params?: QueryBinder, config?: SynchronousQueryOptions): T {\n if (!this[_nativeDb].isOpen())\n throw new IModelError(DbResult.BE_SQLITE_ERROR_NOTOPEN, \"db not open\");\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const stmt = this._statementCache.findAndRemove(ecsql) ?? new ECSqlStatement();\n const executor = new ECSqlRowExecutor(this, stmt, loggerCategory);\n const release = () => {\n executor[Symbol.dispose]();\n releaseECSqlStatement(stmt, this._statementCache, loggerCategory, executor.canCacheStatement);\n };\n try {\n const reader = new ECSqlSyncReader(executor, ecsql, params, config);\n const val = callback(reader);\n if (val instanceof Promise) {\n val.then(release, release);\n } else {\n release();\n }\n return val;\n } catch (err: any) {\n release();\n throw err;\n }\n }\n}\n"]}
@@ -1,7 +1,13 @@
1
1
  import { QueryPropertyMetaData } from "@itwin/core-common";
2
- import { IModelDb } from "./IModelDb";
2
+ import type { IModelDb } from "./IModelDb";
3
+ import { ECSqlStatement } from "./ECSqlStatement";
3
4
  import { IModelJsNative } from "@bentley/imodeljs-native";
4
- import { ECDb } from "./ECDb";
5
+ import type { ECDb } from "./ECDb";
6
+ import type { StatementCache } from "./SqliteStatement";
7
+ /** Returns a statement to its cache, falling back to direct disposal without throwing.
8
+ * @internal
9
+ */
10
+ export declare function releaseECSqlStatement(stmt: ECSqlStatement, cache: StatementCache<ECSqlStatement>, loggerCategory: string, canCache: boolean): void;
5
11
  /**
6
12
  * Executes ECSql queries one row at a time against an IModelDb, maintaining statement state between
7
13
  * successive calls so the caller can page through results via offset-based requests.
@@ -9,15 +15,23 @@ import { ECDb } from "./ECDb";
9
15
  */
10
16
  export declare class ECSqlRowExecutor implements Disposable {
11
17
  private readonly _db;
12
- private _stmt;
18
+ private readonly _stmt;
19
+ private readonly _loggerCategory;
13
20
  private _removeListener;
14
- constructor(_db: IModelDb | ECDb);
15
- /** Disposes the current statement and resets all internal state.
16
- * Invoked when the db signals that the executor must be recycled.
21
+ private _isDisposed;
22
+ private _canCacheStatement;
23
+ /** Whether the statement completed preparation and can be returned to its cache.
24
+ * @internal
25
+ */
26
+ get canCacheStatement(): boolean;
27
+ constructor(_db: IModelDb | ECDb, _stmt: ECSqlStatement, _loggerCategory: string);
28
+ /** Disposes the currently held statement without returning it to the cache.
29
+ * Invoked when the db signals it is closing (the statement cache is cleared on close, so the
30
+ * checked-out statement must be disposed directly to avoid a use-after-free or double dispose).
17
31
  * @internal
18
32
  */
19
33
  private cleanup;
20
- /** Call this function to dispose the row executor off.
34
+ /** Removes the database-close listener owned by this row executor.
21
35
  * @internal
22
36
  */
23
37
  [Symbol.dispose](): void;
@@ -49,14 +63,13 @@ export declare class ECSqlRowExecutor implements Disposable {
49
63
  * @internal
50
64
  */
51
65
  fetchMetadata(options: IModelJsNative.ECSqlRowAdaptorOptions): QueryPropertyMetaData[];
52
- /** Prepares the ECSql statement against the native database and records the elapsed preparation time.
66
+ /** Prepares the ECSql statement when the caller did not supply one from its cache.
53
67
  * @param ecsql - The ECSql text to prepare.
54
68
  * @returns An `OperationResult` indicating success or failure.
55
69
  * @internal
56
70
  */
57
71
  private prepareStmt;
58
- /** Resets the statement and binds the given parameter values. Caches the arguments for later
59
- * comparison so that redundant rebinds can be skipped.
72
+ /** Binds the supplied parameter values to the prepared statement.
60
73
  * @param args - The parameter object to bind, or `undefined` when no parameters are needed.
61
74
  * @returns An `OperationResult` indicating success or failure.
62
75
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlRowExecutor.d.ts","sourceRoot":"","sources":["../../src/ECSqlRowExecutor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAkB9B;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IAK9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHvC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,eAAe,CAAa;gBAEA,GAAG,EAAE,QAAQ,GAAG,IAAI;IAUxD;;;OAGG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAS/B;;;;;;OAMG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAazD;;;;;;;;;;;OAWG;IACI,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,sBAAsB,GAAG,GAAG;IAWvE;;;;;OAKG;IACI,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,sBAAsB,GAAG,qBAAqB,EAAE;IAQ7F;;;;OAIG;IACH,OAAO,CAAC,WAAW;IASnB;;;;;OAKG;IACH,OAAO,CAAC,UAAU;CAWnB"}
1
+ {"version":3,"file":"ECSqlRowExecutor.d.ts","sourceRoot":"","sources":["../../src/ECSqlRowExecutor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAYxD;;GAEG;AAEH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAoBlJ;AAkBD;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IAW9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAmB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAkB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAVlI,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,kBAAkB,CAAQ;IAElC;;OAEG;IACH,IAAW,iBAAiB,IAAI,OAAO,CAAoC;gBAGvC,GAAG,EAAE,QAAQ,GAAG,IAAI,EAAmB,KAAK,EAAE,cAAc,EAAmB,eAAe,EAAE,MAAM;IAQ1I;;;;OAIG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAS/B;;;;;;OAMG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAazD;;;;;;;;;;;OAWG;IACI,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,sBAAsB,GAAG,GAAG;IAWvE;;;;;OAKG;IACI,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,sBAAsB,GAAG,qBAAqB,EAAE;IAU7F;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAkBnB;;;;OAIG;IACH,OAAO,CAAC,UAAU;CAcnB"}
@@ -5,10 +5,46 @@
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.ECSqlRowExecutor = void 0;
8
+ exports.releaseECSqlStatement = releaseECSqlStatement;
8
9
  const core_common_1 = require("@itwin/core-common");
9
- const ECSqlStatement_1 = require("./ECSqlStatement");
10
10
  const core_bentley_1 = require("@itwin/core-bentley");
11
11
  const Symbols_1 = require("./internal/Symbols");
12
+ const statementNotPreparedMessage = "Statement is not prepared. Likely cause: the db was closed before step is called or the ECSqlSyncReader is used outside the context of the callback passed to withQueryReader.";
13
+ function logStatementCleanupError(loggerCategory, message, error) {
14
+ try {
15
+ core_bentley_1.Logger.logTrace(loggerCategory, message, () => ({ error: core_bentley_1.BentleyError.getErrorMessage(error) }));
16
+ }
17
+ catch {
18
+ // Cleanup diagnostics must not replace the original query error.
19
+ }
20
+ }
21
+ /** Returns a statement to its cache, falling back to direct disposal without throwing.
22
+ * @internal
23
+ */
24
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
25
+ function releaseECSqlStatement(stmt, cache, loggerCategory, canCache) {
26
+ if (!canCache || !stmt.isPrepared) {
27
+ try {
28
+ stmt[Symbol.dispose]();
29
+ }
30
+ catch (error) {
31
+ logStatementCleanupError(loggerCategory, "Failed to dispose an ECSQL statement that could not be cached.", error);
32
+ }
33
+ return;
34
+ }
35
+ try {
36
+ cache.addOrDispose(stmt);
37
+ }
38
+ catch (error) {
39
+ try {
40
+ stmt[Symbol.dispose]();
41
+ }
42
+ catch (disposeError) {
43
+ logStatementCleanupError(loggerCategory, "Failed to dispose an ECSQL statement after it could not be returned to the statement cache.", disposeError);
44
+ }
45
+ logStatementCleanupError(loggerCategory, "Failed to return an ECSQL statement to the statement cache; attempted direct disposal instead.", error);
46
+ }
47
+ }
12
48
  // --------------------------------------------------------------------------------------------
13
49
  // ECSqlRowExecutor
14
50
  // --------------------------------------------------------------------------------------------
@@ -19,31 +55,45 @@ const Symbols_1 = require("./internal/Symbols");
19
55
  */
20
56
  class ECSqlRowExecutor {
21
57
  _db;
22
- // eslint-disable-next-line @typescript-eslint/no-deprecated
23
58
  _stmt;
59
+ _loggerCategory;
24
60
  _removeListener;
25
- constructor(_db) {
61
+ _isDisposed = false;
62
+ _canCacheStatement = true;
63
+ /** Whether the statement completed preparation and can be returned to its cache.
64
+ * @internal
65
+ */
66
+ get canCacheStatement() { return this._canCacheStatement; }
67
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
68
+ constructor(_db, _stmt, _loggerCategory) {
26
69
  this._db = _db;
27
- // eslint-disable-next-line @typescript-eslint/no-deprecated
28
- this._stmt = new ECSqlStatement_1.ECSqlStatement();
70
+ this._stmt = _stmt;
71
+ this._loggerCategory = _loggerCategory;
29
72
  this._removeListener = this._db.onBeforeClose.addListener(() => this.cleanup());
30
73
  }
31
74
  // --------------------------------------------------------------------------------------------
32
75
  // Lifecycle
33
76
  // --------------------------------------------------------------------------------------------
34
- /** Disposes the current statement and resets all internal state.
35
- * Invoked when the db signals that the executor must be recycled.
77
+ /** Disposes the currently held statement without returning it to the cache.
78
+ * Invoked when the db signals it is closing (the statement cache is cleared on close, so the
79
+ * checked-out statement must be disposed directly to avoid a use-after-free or double dispose).
36
80
  * @internal
37
81
  */
38
82
  cleanup() {
39
- this._stmt[Symbol.dispose]();
83
+ this._isDisposed = true;
84
+ try {
85
+ this._stmt[Symbol.dispose]();
86
+ }
87
+ catch (error) {
88
+ logStatementCleanupError(this._loggerCategory, "Failed to dispose an ECSQL statement while closing its database.", error);
89
+ }
40
90
  }
41
- /** Call this function to dispose the row executor off.
91
+ /** Removes the database-close listener owned by this row executor.
42
92
  * @internal
43
93
  */
44
94
  [Symbol.dispose]() {
95
+ this._isDisposed = true;
45
96
  this._removeListener();
46
- this.cleanup();
47
97
  }
48
98
  // --------------------------------------------------------------------------------------------
49
99
  // Core execution
@@ -78,8 +128,8 @@ class ECSqlRowExecutor {
78
128
  * @internal
79
129
  */
80
130
  stepNextRow(options) {
81
- if (!this._stmt.isPrepared)
82
- throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, "Statement is not prepared. Likely cause: the db was closed before step is called or the ECSqlSyncReader is used outside the context of the callback passed to withQueryReader.");
131
+ if (this._isDisposed || !this._stmt.isPrepared)
132
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, statementNotPreparedMessage);
83
133
  const stepResult = this._stmt.step();
84
134
  if (stepResult === core_bentley_1.DbResult.BE_SQLITE_ROW)
85
135
  return this._stmt.toRow(options).data;
@@ -94,27 +144,37 @@ class ECSqlRowExecutor {
94
144
  * @internal
95
145
  */
96
146
  fetchMetadata(options) {
147
+ if (this._isDisposed || !this._stmt.isPrepared)
148
+ throw new core_common_1.IModelError(core_bentley_1.DbResult.BE_SQLITE_ERROR, statementNotPreparedMessage);
97
149
  return this._stmt.getMetadata(options).properties;
98
150
  }
99
151
  // --------------------------------------------------------------------------------------------
100
152
  // Execution phases
101
153
  // --------------------------------------------------------------------------------------------
102
- /** Prepares the ECSql statement against the native database and records the elapsed preparation time.
154
+ /** Prepares the ECSql statement when the caller did not supply one from its cache.
103
155
  * @param ecsql - The ECSql text to prepare.
104
156
  * @returns An `OperationResult` indicating success or failure.
105
157
  * @internal
106
158
  */
107
159
  prepareStmt(ecsql) {
160
+ if (this._stmt.isPrepared)
161
+ return { isSuccessful: true };
108
162
  try {
109
163
  this._stmt.prepare(this._db[Symbols_1._nativeDb], ecsql);
110
164
  return { isSuccessful: true };
111
165
  }
112
166
  catch (error) {
167
+ this._canCacheStatement = false;
168
+ try {
169
+ this._stmt[Symbol.dispose]();
170
+ }
171
+ catch (disposeError) {
172
+ logStatementCleanupError(this._loggerCategory, "Failed to dispose an ECSQL statement after preparation failed.", disposeError);
173
+ }
113
174
  return { isSuccessful: false, message: error.message };
114
175
  }
115
176
  }
116
- /** Resets the statement and binds the given parameter values. Caches the arguments for later
117
- * comparison so that redundant rebinds can be skipped.
177
+ /** Binds the supplied parameter values to the prepared statement.
118
178
  * @param args - The parameter object to bind, or `undefined` when no parameters are needed.
119
179
  * @returns An `OperationResult` indicating success or failure.
120
180
  * @internal
@@ -123,6 +183,8 @@ class ECSqlRowExecutor {
123
183
  try {
124
184
  if (args === undefined)
125
185
  return { isSuccessful: true };
186
+ if (!this._stmt.isPrepared)
187
+ return { isSuccessful: false, message: statementNotPreparedMessage };
126
188
  this._stmt.bindParams(args);
127
189
  return { isSuccessful: true };
128
190
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ECSqlRowExecutor.js","sourceRoot":"","sources":["../../src/ECSqlRowExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { IModelError, QueryPropertyMetaData } from \"@itwin/core-common\";\nimport { IModelDb } from \"./IModelDb\";\nimport { ECSqlStatement } from \"./ECSqlStatement\";\nimport { DbResult } from \"@itwin/core-bentley\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport { ECDb } from \"./ECDb\";\n\n// --------------------------------------------------------------------------------------------\n// Internal result types\n// --------------------------------------------------------------------------------------------\n\n/** Result of an internal operation that may fail with a message.\n * @internal\n */\ninterface OperationResult {\n isSuccessful: boolean;\n message?: string;\n}\n\n// --------------------------------------------------------------------------------------------\n// ECSqlRowExecutor\n// --------------------------------------------------------------------------------------------\n\n/**\n * Executes ECSql queries one row at a time against an IModelDb, maintaining statement state between\n * successive calls so the caller can page through results via offset-based requests.\n * @internal\n */\nexport class ECSqlRowExecutor implements Disposable {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n private _stmt: ECSqlStatement;\n private _removeListener: () => void;\n\n public constructor(private readonly _db: IModelDb | ECDb) {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n this._stmt = new ECSqlStatement();\n this._removeListener = this._db.onBeforeClose.addListener(() => this.cleanup());\n }\n\n // --------------------------------------------------------------------------------------------\n // Lifecycle\n // --------------------------------------------------------------------------------------------\n\n /** Disposes the current statement and resets all internal state.\n * Invoked when the db signals that the executor must be recycled.\n * @internal\n */\n private cleanup(): void {\n this._stmt[Symbol.dispose]();\n }\n\n /** Call this function to dispose the row executor off.\n * @internal\n */\n public [Symbol.dispose](): void {\n this._removeListener();\n this.cleanup();\n }\n\n // --------------------------------------------------------------------------------------------\n // Core execution\n // --------------------------------------------------------------------------------------------\n\n /** Prepare the statement and bind parameters in one step.\n * Call once during reader initialization — avoids the per-row `ensureStatementReady` check.\n * @param query - The ECSql text to prepare.\n * @param args - Optional bind parameters.\n * @throws IModelError on preparation or binding failure.\n * @internal\n */\n public prepareAndBind(query: string, args?: object): void {\n\n const prepResult = this.prepareStmt(query);\n if (!prepResult.isSuccessful)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, prepResult.message ?? `Failed to prepare statement: ${query}`);\n\n if (args) {\n const bindResult = this.bindValues(args);\n if (!bindResult.isSuccessful)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, bindResult.message ?? `Failed to bind values: ${query}`);\n }\n }\n\n /** Fast-path: step the cursor once and return row data directly.\n *\n * Returns the row data array if a row is available.\n * Returns `undefined` if the result set is exhausted (DONE).\n *\n * This avoids all intermediate object allocations (StepResult, RowDataResult,\n * DbRuntimeStats, DbQueryResponse) that the general `execute()` path creates per row.\n *\n * @param options - Native row-adaptor options (should be cached and reused across rows).\n * @throws IModelError on step failure or row extraction failure.\n * @internal\n */\n public stepNextRow(options: IModelJsNative.ECSqlRowAdaptorOptions): any {\n if (!this._stmt.isPrepared)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, \"Statement is not prepared. Likely cause: the db was closed before step is called or the ECSqlSyncReader is used outside the context of the callback passed to withQueryReader.\");\n const stepResult = this._stmt.step();\n if (stepResult === DbResult.BE_SQLITE_ROW)\n return this._stmt.toRow(options).data;\n if (stepResult === DbResult.BE_SQLITE_DONE)\n return undefined;\n throw new IModelError(stepResult, `Step failed with code ${stepResult}`);\n }\n\n /** Get column metadata directly from the prepared statement.\n * Call once after `prepareAndBind` — the metadata does not change between rows.\n * @param options - Native row-adaptor options that influence property naming.\n * @returns Array of column metadata.\n * @internal\n */\n public fetchMetadata(options: IModelJsNative.ECSqlRowAdaptorOptions): QueryPropertyMetaData[] {\n return this._stmt.getMetadata(options).properties;\n }\n\n // --------------------------------------------------------------------------------------------\n // Execution phases\n // --------------------------------------------------------------------------------------------\n\n /** Prepares the ECSql statement against the native database and records the elapsed preparation time.\n * @param ecsql - The ECSql text to prepare.\n * @returns An `OperationResult` indicating success or failure.\n * @internal\n */\n private prepareStmt(ecsql: string): OperationResult {\n try {\n this._stmt.prepare(this._db[_nativeDb], ecsql);\n return { isSuccessful: true };\n } catch (error: any) {\n return { isSuccessful: false, message: error.message };\n }\n }\n\n /** Resets the statement and binds the given parameter values. Caches the arguments for later\n * comparison so that redundant rebinds can be skipped.\n * @param args - The parameter object to bind, or `undefined` when no parameters are needed.\n * @returns An `OperationResult` indicating success or failure.\n * @internal\n */\n private bindValues(args: object | undefined): OperationResult {\n try {\n if (args === undefined)\n return { isSuccessful: true };\n\n this._stmt.bindParams(args);\n return { isSuccessful: true };\n } catch (error: any) {\n return { isSuccessful: false, message: error.message };\n }\n }\n}"]}
1
+ {"version":3,"file":"ECSqlRowExecutor.js","sourceRoot":"","sources":["../../src/ECSqlRowExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { IModelError, QueryPropertyMetaData } from \"@itwin/core-common\";\nimport type { IModelDb } from \"./IModelDb\";\nimport { ECSqlStatement } from \"./ECSqlStatement\";\nimport { BentleyError, DbResult, Logger } from \"@itwin/core-bentley\";\nimport { IModelJsNative } from \"@bentley/imodeljs-native\";\nimport { _nativeDb } from \"./internal/Symbols\";\nimport type { ECDb } from \"./ECDb\";\nimport type { StatementCache } from \"./SqliteStatement\";\n\nconst statementNotPreparedMessage = \"Statement is not prepared. Likely cause: the db was closed before step is called or the ECSqlSyncReader is used outside the context of the callback passed to withQueryReader.\";\n\nfunction logStatementCleanupError(loggerCategory: string, message: string, error: unknown): void {\n try {\n Logger.logTrace(loggerCategory, message, () => ({ error: BentleyError.getErrorMessage(error) }));\n } catch {\n // Cleanup diagnostics must not replace the original query error.\n }\n}\n\n/** Returns a statement to its cache, falling back to direct disposal without throwing.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nexport function releaseECSqlStatement(stmt: ECSqlStatement, cache: StatementCache<ECSqlStatement>, loggerCategory: string, canCache: boolean): void {\n if (!canCache || !stmt.isPrepared) {\n try {\n stmt[Symbol.dispose]();\n } catch (error) {\n logStatementCleanupError(loggerCategory, \"Failed to dispose an ECSQL statement that could not be cached.\", error);\n }\n return;\n }\n\n try {\n cache.addOrDispose(stmt);\n } catch (error) {\n try {\n stmt[Symbol.dispose]();\n } catch (disposeError) {\n logStatementCleanupError(loggerCategory, \"Failed to dispose an ECSQL statement after it could not be returned to the statement cache.\", disposeError);\n }\n logStatementCleanupError(loggerCategory, \"Failed to return an ECSQL statement to the statement cache; attempted direct disposal instead.\", error);\n }\n}\n\n// --------------------------------------------------------------------------------------------\n// Internal result types\n// --------------------------------------------------------------------------------------------\n\n/** Result of an internal operation that may fail with a message.\n * @internal\n */\ninterface OperationResult {\n isSuccessful: boolean;\n message?: string;\n}\n\n// --------------------------------------------------------------------------------------------\n// ECSqlRowExecutor\n// --------------------------------------------------------------------------------------------\n\n/**\n * Executes ECSql queries one row at a time against an IModelDb, maintaining statement state between\n * successive calls so the caller can page through results via offset-based requests.\n * @internal\n */\nexport class ECSqlRowExecutor implements Disposable {\n private _removeListener: () => void;\n private _isDisposed = false;\n private _canCacheStatement = true;\n\n /** Whether the statement completed preparation and can be returned to its cache.\n * @internal\n */\n public get canCacheStatement(): boolean { return this._canCacheStatement; }\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n public constructor(private readonly _db: IModelDb | ECDb, private readonly _stmt: ECSqlStatement, private readonly _loggerCategory: string) {\n this._removeListener = this._db.onBeforeClose.addListener(() => this.cleanup());\n }\n\n // --------------------------------------------------------------------------------------------\n // Lifecycle\n // --------------------------------------------------------------------------------------------\n\n /** Disposes the currently held statement without returning it to the cache.\n * Invoked when the db signals it is closing (the statement cache is cleared on close, so the\n * checked-out statement must be disposed directly to avoid a use-after-free or double dispose).\n * @internal\n */\n private cleanup(): void {\n this._isDisposed = true;\n try {\n this._stmt[Symbol.dispose]();\n } catch (error) {\n logStatementCleanupError(this._loggerCategory, \"Failed to dispose an ECSQL statement while closing its database.\", error);\n }\n }\n\n /** Removes the database-close listener owned by this row executor.\n * @internal\n */\n public [Symbol.dispose](): void {\n this._isDisposed = true;\n this._removeListener();\n }\n\n // --------------------------------------------------------------------------------------------\n // Core execution\n // --------------------------------------------------------------------------------------------\n\n /** Prepare the statement and bind parameters in one step.\n * Call once during reader initialization — avoids the per-row `ensureStatementReady` check.\n * @param query - The ECSql text to prepare.\n * @param args - Optional bind parameters.\n * @throws IModelError on preparation or binding failure.\n * @internal\n */\n public prepareAndBind(query: string, args?: object): void {\n\n const prepResult = this.prepareStmt(query);\n if (!prepResult.isSuccessful)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, prepResult.message ?? `Failed to prepare statement: ${query}`);\n\n if (args) {\n const bindResult = this.bindValues(args);\n if (!bindResult.isSuccessful)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, bindResult.message ?? `Failed to bind values: ${query}`);\n }\n }\n\n /** Fast-path: step the cursor once and return row data directly.\n *\n * Returns the row data array if a row is available.\n * Returns `undefined` if the result set is exhausted (DONE).\n *\n * This avoids all intermediate object allocations (StepResult, RowDataResult,\n * DbRuntimeStats, DbQueryResponse) that the general `execute()` path creates per row.\n *\n * @param options - Native row-adaptor options (should be cached and reused across rows).\n * @throws IModelError on step failure or row extraction failure.\n * @internal\n */\n public stepNextRow(options: IModelJsNative.ECSqlRowAdaptorOptions): any {\n if (this._isDisposed || !this._stmt.isPrepared)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, statementNotPreparedMessage);\n const stepResult = this._stmt.step();\n if (stepResult === DbResult.BE_SQLITE_ROW)\n return this._stmt.toRow(options).data;\n if (stepResult === DbResult.BE_SQLITE_DONE)\n return undefined;\n throw new IModelError(stepResult, `Step failed with code ${stepResult}`);\n }\n\n /** Get column metadata directly from the prepared statement.\n * Call once after `prepareAndBind` — the metadata does not change between rows.\n * @param options - Native row-adaptor options that influence property naming.\n * @returns Array of column metadata.\n * @internal\n */\n public fetchMetadata(options: IModelJsNative.ECSqlRowAdaptorOptions): QueryPropertyMetaData[] {\n if (this._isDisposed || !this._stmt.isPrepared)\n throw new IModelError(DbResult.BE_SQLITE_ERROR, statementNotPreparedMessage);\n return this._stmt.getMetadata(options).properties;\n }\n\n // --------------------------------------------------------------------------------------------\n // Execution phases\n // --------------------------------------------------------------------------------------------\n\n /** Prepares the ECSql statement when the caller did not supply one from its cache.\n * @param ecsql - The ECSql text to prepare.\n * @returns An `OperationResult` indicating success or failure.\n * @internal\n */\n private prepareStmt(ecsql: string): OperationResult {\n if (this._stmt.isPrepared)\n return { isSuccessful: true };\n\n try {\n this._stmt.prepare(this._db[_nativeDb], ecsql);\n return { isSuccessful: true };\n } catch (error: any) {\n this._canCacheStatement = false;\n try {\n this._stmt[Symbol.dispose]();\n } catch (disposeError) {\n logStatementCleanupError(this._loggerCategory, \"Failed to dispose an ECSQL statement after preparation failed.\", disposeError);\n }\n return { isSuccessful: false, message: error.message };\n }\n }\n\n /** Binds the supplied parameter values to the prepared statement.\n * @param args - The parameter object to bind, or `undefined` when no parameters are needed.\n * @returns An `OperationResult` indicating success or failure.\n * @internal\n */\n private bindValues(args: object | undefined): OperationResult {\n try {\n if (args === undefined)\n return { isSuccessful: true };\n\n if (!this._stmt.isPrepared)\n return { isSuccessful: false, message: statementNotPreparedMessage };\n\n this._stmt.bindParams(args);\n return { isSuccessful: true };\n } catch (error: any) {\n return { isSuccessful: false, message: error.message };\n }\n }\n}"]}
@@ -580,7 +580,8 @@ export declare abstract class IModelDb extends IModel {
580
580
  * @param config Allow to specify certain flags which control how query is executed.
581
581
  * @returns the value returned by `callback`.
582
582
  * @throws IModelError if db is not open.
583
- * Should be used when we want true step by step behaviour from the reader without any intermediate caching involved.
583
+ * Use this method for true step-by-step row consumption without intermediate result or page caching.
584
+ * The prepared ECSQL statement may be reused from the statement cache between completed calls.
584
585
  * @beta
585
586
  * */
586
587
  withQueryReader<T>(ecsql: string, callback: (reader: ECSqlSyncReader) => T, params?: QueryBinder, config?: SynchronousQueryOptions): T;