@ocap/indexdb-sqlite 1.29.10 → 1.29.11

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.
package/esm/db/base.mjs CHANGED
@@ -56,6 +56,7 @@ var SqliteBaseIndexDB = class extends BaseIndexDB {
56
56
  });
57
57
  let qb = this.db.selectFrom("tx").selectAll();
58
58
  const isMutual = !!(sender && receiver && direction === "MUTUAL");
59
+ const isUnion = !!(sender && receiver && direction !== "MUTUAL" && direction !== "ONE_WAY");
59
60
  if (sender && receiver) if (direction === "MUTUAL") {} else if (direction === "ONE_WAY") qb = qb.where("sender", "=", sender).where("receiver", "=", receiver);
60
61
  else qb = qb.where((eb) => eb.or([eb("sender", "=", sender), eb("receiver", "=", receiver)]));
61
62
  else if (sender) qb = qb.where("sender", "=", sender);
@@ -104,22 +105,52 @@ var SqliteBaseIndexDB = class extends BaseIndexDB {
104
105
  if (delegations.length) activeJsonFilters.push(["delegation", delegations]);
105
106
  if (tokenFactories.length) activeJsonFilters.push(["tokenFactory", tokenFactories]);
106
107
  const hasNonJsonFilters = !!(sender || receiver || types.length || txs.length || parsedStart || parsedEnd || validity);
108
+ const isUnionOnly = isUnion && !types.length && !txs.length && !parsedStart && !parsedEnd && !validity && activeJsonFilters.length === 0;
109
+ const isMultiTypeOnly = types.length > 1 && !sender && !receiver && !txs.length && !parsedStart && !parsedEnd && !validity && activeJsonFilters.length === 0;
107
110
  if (isMutual) {
108
111
  const [c1, c2] = await Promise.all([this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).where("receiver", "=", receiver).executeTakeFirst(), this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", receiver).where("receiver", "=", sender).executeTakeFirst()]);
109
112
  total = (c1?.count ?? 0) + (c2?.count ?? 0);
110
113
  } else if (!hasNonJsonFilters && activeJsonFilters.length === 1) {
111
114
  const [refType, values] = activeJsonFilters[0];
112
115
  total = (await this.db.selectFrom("tx_ref").select(this.db.fn.countAll().as("count")).where("type", "=", refType).where("value", "in", values).executeTakeFirst())?.count ?? 0;
113
- } else if (sender && receiver && direction !== "ONE_WAY") {
114
- const [senderCount, receiverCount] = await Promise.all([this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).executeTakeFirst(), this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("receiver", "=", receiver).executeTakeFirst()]);
115
- total = (senderCount?.count ?? 0) + (receiverCount?.count ?? 0);
116
- } else total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
116
+ } else if (isUnionOnly) {
117
+ const [senderCount, receiverCount, overlapCount] = await Promise.all([
118
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).executeTakeFirst(),
119
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("receiver", "=", receiver).executeTakeFirst(),
120
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).where("receiver", "=", receiver).executeTakeFirst()
121
+ ]);
122
+ total = (senderCount?.count ?? 0) + (receiverCount?.count ?? 0) - (overlapCount?.count ?? 0);
123
+ } else if (isMultiTypeOnly) total = (await Promise.all(types.map((t) => this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("type", "=", t).executeTakeFirst()))).reduce((sum, c) => sum + (c?.count ?? 0), 0);
124
+ else if (!hasNonJsonFilters && activeJsonFilters.length === 0) total = (await sql`SELECT max(rowid) as c FROM tx`.execute(this.db)).rows[0]?.c ?? 0;
125
+ else total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
117
126
  const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
118
127
  let rawResults;
119
128
  if (isMutual) {
120
129
  const q1 = this.db.selectFrom("tx").selectAll().where("sender", "=", sender).where("receiver", "=", receiver);
121
130
  const q2 = this.db.selectFrom("tx").selectAll().where("sender", "=", receiver).where("receiver", "=", sender);
122
131
  rawResults = await q1.unionAll(q2).orderBy(pagination.order.field, orderDir).limit(pagination.size).offset(pagination.cursor).execute();
132
+ } else if (isUnionOnly) {
133
+ const topN = pagination.cursor + pagination.size;
134
+ const dirRaw = sql.raw(orderDir === "desc" ? "DESC" : "ASC");
135
+ const colRef = sql.ref(pagination.order.field);
136
+ rawResults = (await sql`
137
+ SELECT * FROM (
138
+ SELECT * FROM (SELECT * FROM tx WHERE sender = ${sender} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})
139
+ UNION
140
+ SELECT * FROM (SELECT * FROM tx WHERE receiver = ${receiver} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})
141
+ ) ORDER BY ${colRef} ${dirRaw}
142
+ LIMIT ${pagination.size} OFFSET ${pagination.cursor}
143
+ `.execute(this.db)).rows;
144
+ } else if (isMultiTypeOnly) {
145
+ const topN = pagination.cursor + pagination.size;
146
+ const dirRaw = sql.raw(orderDir === "desc" ? "DESC" : "ASC");
147
+ const colRef = sql.ref(pagination.order.field);
148
+ let unionQuery = sql`SELECT * FROM (SELECT * FROM tx WHERE type = ${types[0]} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})`;
149
+ for (let i = 1; i < types.length; i++) unionQuery = sql`${unionQuery} UNION ALL SELECT * FROM (SELECT * FROM tx WHERE type = ${types[i]} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})`;
150
+ rawResults = (await sql`
151
+ SELECT * FROM (${unionQuery}) ORDER BY ${colRef} ${dirRaw}
152
+ LIMIT ${pagination.size} OFFSET ${pagination.cursor}
153
+ `.execute(this.db)).rows;
123
154
  } else if (!hasNonJsonFilters && activeJsonFilters.length === 1 && pagination.order.field === "time") {
124
155
  const [refType, values] = activeJsonFilters[0];
125
156
  const hashes = (await this.db.selectFrom("tx_ref").select("hash").where("type", "=", refType).where("value", "in", values).orderBy("time", orderDir).limit(pagination.size).offset(pagination.cursor).execute()).map((r) => r.hash);
package/lib/db/base.cjs CHANGED
@@ -60,6 +60,7 @@ var SqliteBaseIndexDB = class extends _ocap_indexdb.BaseIndexDB {
60
60
  });
61
61
  let qb = this.db.selectFrom("tx").selectAll();
62
62
  const isMutual = !!(sender && receiver && direction === "MUTUAL");
63
+ const isUnion = !!(sender && receiver && direction !== "MUTUAL" && direction !== "ONE_WAY");
63
64
  if (sender && receiver) if (direction === "MUTUAL") {} else if (direction === "ONE_WAY") qb = qb.where("sender", "=", sender).where("receiver", "=", receiver);
64
65
  else qb = qb.where((eb) => eb.or([eb("sender", "=", sender), eb("receiver", "=", receiver)]));
65
66
  else if (sender) qb = qb.where("sender", "=", sender);
@@ -108,22 +109,52 @@ var SqliteBaseIndexDB = class extends _ocap_indexdb.BaseIndexDB {
108
109
  if (delegations.length) activeJsonFilters.push(["delegation", delegations]);
109
110
  if (tokenFactories.length) activeJsonFilters.push(["tokenFactory", tokenFactories]);
110
111
  const hasNonJsonFilters = !!(sender || receiver || types.length || txs.length || parsedStart || parsedEnd || validity);
112
+ const isUnionOnly = isUnion && !types.length && !txs.length && !parsedStart && !parsedEnd && !validity && activeJsonFilters.length === 0;
113
+ const isMultiTypeOnly = types.length > 1 && !sender && !receiver && !txs.length && !parsedStart && !parsedEnd && !validity && activeJsonFilters.length === 0;
111
114
  if (isMutual) {
112
115
  const [c1, c2] = await Promise.all([this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).where("receiver", "=", receiver).executeTakeFirst(), this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", receiver).where("receiver", "=", sender).executeTakeFirst()]);
113
116
  total = (c1?.count ?? 0) + (c2?.count ?? 0);
114
117
  } else if (!hasNonJsonFilters && activeJsonFilters.length === 1) {
115
118
  const [refType, values] = activeJsonFilters[0];
116
119
  total = (await this.db.selectFrom("tx_ref").select(this.db.fn.countAll().as("count")).where("type", "=", refType).where("value", "in", values).executeTakeFirst())?.count ?? 0;
117
- } else if (sender && receiver && direction !== "ONE_WAY") {
118
- const [senderCount, receiverCount] = await Promise.all([this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).executeTakeFirst(), this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("receiver", "=", receiver).executeTakeFirst()]);
119
- total = (senderCount?.count ?? 0) + (receiverCount?.count ?? 0);
120
- } else total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
120
+ } else if (isUnionOnly) {
121
+ const [senderCount, receiverCount, overlapCount] = await Promise.all([
122
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).executeTakeFirst(),
123
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("receiver", "=", receiver).executeTakeFirst(),
124
+ this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("sender", "=", sender).where("receiver", "=", receiver).executeTakeFirst()
125
+ ]);
126
+ total = (senderCount?.count ?? 0) + (receiverCount?.count ?? 0) - (overlapCount?.count ?? 0);
127
+ } else if (isMultiTypeOnly) total = (await Promise.all(types.map((t) => this.db.selectFrom("tx").select(this.db.fn.countAll().as("count")).where("type", "=", t).executeTakeFirst()))).reduce((sum, c) => sum + (c?.count ?? 0), 0);
128
+ else if (!hasNonJsonFilters && activeJsonFilters.length === 0) total = (await kysely.sql`SELECT max(rowid) as c FROM tx`.execute(this.db)).rows[0]?.c ?? 0;
129
+ else total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
121
130
  const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
122
131
  let rawResults;
123
132
  if (isMutual) {
124
133
  const q1 = this.db.selectFrom("tx").selectAll().where("sender", "=", sender).where("receiver", "=", receiver);
125
134
  const q2 = this.db.selectFrom("tx").selectAll().where("sender", "=", receiver).where("receiver", "=", sender);
126
135
  rawResults = await q1.unionAll(q2).orderBy(pagination.order.field, orderDir).limit(pagination.size).offset(pagination.cursor).execute();
136
+ } else if (isUnionOnly) {
137
+ const topN = pagination.cursor + pagination.size;
138
+ const dirRaw = kysely.sql.raw(orderDir === "desc" ? "DESC" : "ASC");
139
+ const colRef = kysely.sql.ref(pagination.order.field);
140
+ rawResults = (await kysely.sql`
141
+ SELECT * FROM (
142
+ SELECT * FROM (SELECT * FROM tx WHERE sender = ${sender} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})
143
+ UNION
144
+ SELECT * FROM (SELECT * FROM tx WHERE receiver = ${receiver} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})
145
+ ) ORDER BY ${colRef} ${dirRaw}
146
+ LIMIT ${pagination.size} OFFSET ${pagination.cursor}
147
+ `.execute(this.db)).rows;
148
+ } else if (isMultiTypeOnly) {
149
+ const topN = pagination.cursor + pagination.size;
150
+ const dirRaw = kysely.sql.raw(orderDir === "desc" ? "DESC" : "ASC");
151
+ const colRef = kysely.sql.ref(pagination.order.field);
152
+ let unionQuery = kysely.sql`SELECT * FROM (SELECT * FROM tx WHERE type = ${types[0]} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})`;
153
+ for (let i = 1; i < types.length; i++) unionQuery = kysely.sql`${unionQuery} UNION ALL SELECT * FROM (SELECT * FROM tx WHERE type = ${types[i]} ORDER BY ${colRef} ${dirRaw} LIMIT ${topN})`;
154
+ rawResults = (await kysely.sql`
155
+ SELECT * FROM (${unionQuery}) ORDER BY ${colRef} ${dirRaw}
156
+ LIMIT ${pagination.size} OFFSET ${pagination.cursor}
157
+ `.execute(this.db)).rows;
127
158
  } else if (!hasNonJsonFilters && activeJsonFilters.length === 1 && pagination.order.field === "time") {
128
159
  const [refType, values] = activeJsonFilters[0];
129
160
  const hashes = (await this.db.selectFrom("tx_ref").select("hash").where("type", "=", refType).where("value", "in", values).orderBy("time", orderDir).limit(pagination.size).offset(pagination.cursor).execute()).map((r) => r.hash);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ocap/indexdb-sqlite",
3
3
  "description": "OCAP indexdb adapter that uses SQLite as backend",
4
- "version": "1.29.10",
4
+ "version": "1.29.11",
5
5
  "author": "wangshijun <shijun@arcblock.io> (https://www.arcblock.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/ArcBlock/blockchain/issues",
@@ -14,7 +14,7 @@
14
14
  "wangshijun <shijun@arcblock.io> (https://www.arcblock.io)"
15
15
  ],
16
16
  "devDependencies": {
17
- "@ocap/indexdb-test": "1.29.10"
17
+ "@ocap/indexdb-test": "1.29.11"
18
18
  },
19
19
  "homepage": "https://github.com/ArcBlock/blockchain/tree/master/indexdb/sqlite",
20
20
  "keywords": [
@@ -63,10 +63,10 @@
63
63
  "clean": "rm -rf lib esm"
64
64
  },
65
65
  "dependencies": {
66
- "@arcblock/did": "1.29.10",
67
- "@ocap/indexdb": "1.29.10",
68
- "@ocap/types": "1.29.10",
69
- "@ocap/util": "1.29.10",
66
+ "@arcblock/did": "1.29.11",
67
+ "@ocap/indexdb": "1.29.11",
68
+ "@ocap/types": "1.29.11",
69
+ "@ocap/util": "1.29.11",
70
70
  "debug": "^4.4.3",
71
71
  "better-sqlite3": "^11.8.1",
72
72
  "kysely": "^0.27.0",