base-link-core 0.3.15 → 0.3.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.
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## 成员
21
21
 
22
- - 信封(`src/envelope.ts`):`ENVELOPE_VERSION` 版本常量;`ENVELOPE_SHAPES` 6 形状(`list`/`detail`/`stat`/`receipt`/`analysis`/`fallback`);`Envelope`/`EnvelopeShape`/`EnvelopeDataByShape` 类型;`createEnvelope` 造封、`parseEnvelope` 验封、`isEnvelope` 判定。
22
+ - 信封(`src/envelope.ts`):`ENVELOPE_VERSION` 版本常量;`ENVELOPE_SHAPES` 7 形状(`list`/`detail`/`stat`/`receipt`/`analysis`/`fallback`/`resultset`);`Envelope`/`EnvelopeShape`/`EnvelopeDataByShape` 类型;`createEnvelope` 造封、`parseEnvelope` 验封、`isEnvelope` 判定。
23
23
  - 注册(`src/registry.ts`):`RegistryKey`/`ParsedKey`/`Registry` 类型;`parseRegistryKey` 拆命令三段;`createRegistry(knownKeys)` 建表。
24
24
  - 执行(`src/runner.ts`):`RunRequest` 请求形(命令+形状+参数)、`Fetcher` 取数器类型、`runCombo(registry, req, fetchData)` 跑一次联动(key 先过注册表、载荷再过信封全字段)。
25
25
  - 错误(`src/errors.ts`):`LinkCoreError` 基类下分 `EnvelopeError`/`RegistryError`/`RunnerError`/`ConfigError` 四域。
@@ -0,0 +1,67 @@
1
+ /**
2
+ * #958 · 数据族分页与续取件:页大小校验、不透明凭据编解码、游标/偏移条件装配。
3
+ *
4
+ * 住公共层(`base-link-core`)的理由:`docs/agents/数据族-规格.md` §六——
5
+ * 查询单解析、目录校验、结果集装配住公共层;`§四③` 续取凭据按查询类型自选
6
+ * (行查询走游标、聚合查询走偏移),故本件与引擎件(`data-query.ts`)同住。
7
+ *
8
+ * 范围:`page.size` 校验(缺省与上限可调,见遗留出口)+ `page.next`
9
+ * 不透明凭据(篡改/乱填按项拒,报文可读)+ 查询指纹绑定(换查询单须从
10
+ * 第一页重取)+ 行查询游标条件(`ORDER BY` 全序 + `rowid` 系链,`NULL`
11
+ * 安全)+ 聚合查询偏移载荷(端到端待 #957 聚合落地后接线,本件先给编解码)。
12
+ *
13
+ * 零运行时依赖:只用全局 `TextEncoder`/`TextDecoder`(Node ≥18 自带,无 import),
14
+ * 不 import `node:` 件,不引第三方;库句柄不碰(本件只算 SQL 片与凭据,不管库)。
15
+ * 类型上写得出具体形状:无 `any`,未知输入先收窄再读。
16
+ * 只读:本件不跑 SQL,只产 SQL 片与凭据串;不建表、不写库、不产文件。
17
+ */
18
+ /** 页大小缺省(遗留出口:取值口径另议,本数只作可调参数的初值)。 */
19
+ export declare const DEFAULT_PAGE_SIZE = 100;
20
+ /** 页大小上限(遗留出口:取值口径另议,本数只作可调参数的初值)。 */
21
+ export declare const MAX_PAGE_SIZE = 1000;
22
+ /** 读 `page`:缺省即第一页(缺省大小);`page` 出现须为对象;`size`/`next` 各自校验。 */
23
+ export declare function readPage(rawPage: unknown, from: string): {
24
+ size: number;
25
+ next: string | null;
26
+ };
27
+ /**
28
+ * 查询指纹(换查询单须从第一页重取的绑定依据)。
29
+ * 只含语义(`from`/`join`/`select`/`where`/`orderBy`/`groupBy`/`agg`),
30
+ * 不含 `id`(调用方标识,原样回而已)与 `page`(表现层:大小可换页,凭据是状态)。
31
+ */
32
+ export declare function fingerprintQuery(raw: Record<string, unknown>): string;
33
+ /** 行查询凭据编码(游标:排序列值 + `rowid` 系链;值原样进 JSON,`NULL` 即 `null`)。 */
34
+ export declare function encodeRowToken(fingerprint: string, orderingValues: readonly unknown[], rowids: readonly (number | null)[]): string;
35
+ /** 行查询凭据解码(种类/指纹/形状逐项验,错即按项拒,报文可读)。 */
36
+ export declare function decodeRowToken(token: string, expectedFingerprint: string, expectedOrderLen: number, expectedRowidLen: number): {
37
+ orderingValues: unknown[];
38
+ rowids: (number | null)[];
39
+ };
40
+ /** 聚合查询凭据编码(偏移:已跳过多少组;端到端待 #957 聚合落地后接线)。 */
41
+ export declare function encodeAggToken(fingerprint: string, offset: number): string;
42
+ /** 聚合查询凭据解码(种类/指纹/偏移逐项验,错即按项拒)。 */
43
+ export declare function decodeAggToken(token: string, expectedFingerprint: string): number;
44
+ /** 排序列(含方向)+ 上一页末行值(`NULL` 即 `null`,`rowid` 系链永不为 `NULL`)。 */
45
+ export interface CursorOrderSpec {
46
+ readonly table: string | null;
47
+ readonly column: string;
48
+ readonly dir: 'ASC' | 'DESC';
49
+ readonly lastValue: unknown;
50
+ }
51
+ /** `rowid` 系链(一表一链,两表两链,恒 `ASC`;`from` 永不为 `NULL`,`LEFT` 失配时 `join` 可为 `NULL`)。 */
52
+ export interface CursorRowidSpec {
53
+ readonly table: string | null;
54
+ readonly lastRowid: number | null;
55
+ }
56
+ /**
57
+ * 游标条件(`ORDER BY` 全序的“下一页”:元组大于上一页末行,`NULL` 安全)。
58
+ * `ASC`(`NULL` 居首):末值 `NULL` → 后继为非 `NULL`;末值非 `NULL` → 后继为更大值。
59
+ * `DESC`(`NULL` 居尾):末值 `NULL` → 本列无后继(靠系链);末值非 `NULL` → 后继为更小值或 `NULL`。
60
+ * 系链(`rowid ASC`):后继恒为更大行号。
61
+ * 返回不带 `WHERE` 关键字的片段,调用方与用户条件按 `AND` 拼。
62
+ */
63
+ export declare function buildCursorCondition(orders: readonly CursorOrderSpec[], rowids: readonly CursorRowidSpec[]): {
64
+ sql: string;
65
+ params: (string | number | null)[];
66
+ };
67
+ //# sourceMappingURL=data-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-page.d.ts","sourceRoot":"","sources":["../src/data-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,sCAAsC;AACtC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,sCAAsC;AACtC,eAAO,MAAM,aAAa,OAAO,CAAC;AAgBlC,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAO9F;AAkFD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAYrE;AAsDD,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,SAAS,OAAO,EAAE,EAClC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAC,IAAI,CAAC,EAAE,GAC/B,MAAM,CAGR;AAED,uCAAuC;AACvC,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,mBAAmB,EAAE,MAAM,EAC3B,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB;IAAE,cAAc,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,GAAC,IAAI,CAAC,EAAE,CAAA;CAAE,CA6BxD;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAM1E;AAED,mCAAmC;AACnC,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAgBjF;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAcD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;CAAE,CAwDrD"}
@@ -0,0 +1,313 @@
1
+ /**
2
+ * #958 · 数据族分页与续取件:页大小校验、不透明凭据编解码、游标/偏移条件装配。
3
+ *
4
+ * 住公共层(`base-link-core`)的理由:`docs/agents/数据族-规格.md` §六——
5
+ * 查询单解析、目录校验、结果集装配住公共层;`§四③` 续取凭据按查询类型自选
6
+ * (行查询走游标、聚合查询走偏移),故本件与引擎件(`data-query.ts`)同住。
7
+ *
8
+ * 范围:`page.size` 校验(缺省与上限可调,见遗留出口)+ `page.next`
9
+ * 不透明凭据(篡改/乱填按项拒,报文可读)+ 查询指纹绑定(换查询单须从
10
+ * 第一页重取)+ 行查询游标条件(`ORDER BY` 全序 + `rowid` 系链,`NULL`
11
+ * 安全)+ 聚合查询偏移载荷(端到端待 #957 聚合落地后接线,本件先给编解码)。
12
+ *
13
+ * 零运行时依赖:只用全局 `TextEncoder`/`TextDecoder`(Node ≥18 自带,无 import),
14
+ * 不 import `node:` 件,不引第三方;库句柄不碰(本件只算 SQL 片与凭据,不管库)。
15
+ * 类型上写得出具体形状:无 `any`,未知输入先收窄再读。
16
+ * 只读:本件不跑 SQL,只产 SQL 片与凭据串;不建表、不写库、不产文件。
17
+ */
18
+ import { LinkCoreError } from './errors.js';
19
+ /** 页大小缺省(遗留出口:取值口径另议,本数只作可调参数的初值)。 */
20
+ export const DEFAULT_PAGE_SIZE = 100;
21
+ /** 页大小上限(遗留出口:取值口径另议,本数只作可调参数的初值)。 */
22
+ export const MAX_PAGE_SIZE = 1000;
23
+ /** 凭据盐(篡改探测用:盲改不断校验即拒;源码公开故不作安全边界,只防误用与乱填)。 */
24
+ const PAGE_SALT = 'ilife-data-page-v1';
25
+ /** 凭据版本(解码时不认即拒,报文可读)。 */
26
+ const TOKEN_VERSION = 1;
27
+ function fail(code, message) {
28
+ throw new LinkCoreError(code, message);
29
+ }
30
+ function isRecord(v) {
31
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
32
+ }
33
+ /** 读 `page`:缺省即第一页(缺省大小);`page` 出现须为对象;`size`/`next` 各自校验。 */
34
+ export function readPage(rawPage, from) {
35
+ if (rawPage === undefined)
36
+ return { size: DEFAULT_PAGE_SIZE, next: null };
37
+ if (!isRecord(rawPage)) {
38
+ fail('DATA_QUERY_INVALID', from + ' 的 page 须为对象(含 size/next)');
39
+ }
40
+ const rec = rawPage;
41
+ return { size: readPageSize(rec['size'], from), next: readPageNext(rec['next'], from) };
42
+ }
43
+ function readPageSize(rawSize, from) {
44
+ if (rawSize === undefined)
45
+ return DEFAULT_PAGE_SIZE;
46
+ if (typeof rawSize !== 'number' || !Number.isInteger(rawSize)) {
47
+ fail('DATA_QUERY_INVALID', from + ' 的 page.size 须为 1~' + MAX_PAGE_SIZE + ' 的整数(实际:' + String(rawSize) + ')');
48
+ }
49
+ const size = rawSize;
50
+ if (size < 1 || size > MAX_PAGE_SIZE) {
51
+ fail('DATA_QUERY_INVALID', from + ' 的 page.size 须为 1~' + MAX_PAGE_SIZE + ' 的整数(实际:' + String(size) + ')');
52
+ }
53
+ return size;
54
+ }
55
+ function readPageNext(rawNext, from) {
56
+ if (rawNext === undefined || rawNext === null)
57
+ return null;
58
+ if (typeof rawNext !== 'string' || rawNext.length === 0) {
59
+ fail('DATA_QUERY_INVALID', from + ' 的 page.next 须为字符串凭据或 null(乱填的凭据按项拒)');
60
+ }
61
+ return rawNext;
62
+ }
63
+ /** 规范化(指纹用):递归排键,数组保序,标量原样;`undefined` 视为缺席(与缺键同形)。 */
64
+ function canonicalize(v) {
65
+ if (Array.isArray(v))
66
+ return v.map(canonicalize);
67
+ if (isRecord(v)) {
68
+ const out = {};
69
+ for (const k of Object.keys(v).sort()) {
70
+ const item = v[k];
71
+ if (item === undefined)
72
+ continue;
73
+ out[k] = canonicalize(item);
74
+ }
75
+ return out;
76
+ }
77
+ return v;
78
+ }
79
+ function utf8Bytes(s) {
80
+ return new TextEncoder().encode(s);
81
+ }
82
+ function utf8String(b) {
83
+ return new TextDecoder('utf-8', { fatal: true }).decode(b);
84
+ }
85
+ /** FNV-1a 32 位(指纹与校验共用,纯函数,无依赖)。 */
86
+ function fnv1a(bytes) {
87
+ let h = 2166136261;
88
+ for (const byte of bytes) {
89
+ h ^= byte;
90
+ h = Math.imul(h, 16777619) >>> 0;
91
+ }
92
+ return h >>> 0;
93
+ }
94
+ function hexOf(bytes) {
95
+ let s = '';
96
+ for (const b of bytes) {
97
+ const h = b.toString(16);
98
+ s += h.length === 1 ? '0' + h : h;
99
+ }
100
+ return s;
101
+ }
102
+ function bytesOfHex(hex) {
103
+ if (hex.length % 2 !== 0)
104
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(十六进制长度须为偶数)');
105
+ const out = new Uint8Array(hex.length / 2);
106
+ for (let i = 0; i < out.length; i += 1) {
107
+ const pair = hex.slice(i * 2, i * 2 + 2);
108
+ if (!/^[0-9a-fA-F]{2}$/.test(pair)) {
109
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(非十六进制字符)');
110
+ }
111
+ out[i] = parseInt(pair, 16);
112
+ }
113
+ return out;
114
+ }
115
+ function checksumOf(payloadJson) {
116
+ const h = fnv1a(utf8Bytes(PAGE_SALT + '.' + payloadJson));
117
+ return h.toString(16).padStart(8, '0');
118
+ }
119
+ /**
120
+ * 查询指纹(换查询单须从第一页重取的绑定依据)。
121
+ * 只含语义(`from`/`join`/`select`/`where`/`orderBy`/`groupBy`/`agg`),
122
+ * 不含 `id`(调用方标识,原样回而已)与 `page`(表现层:大小可换页,凭据是状态)。
123
+ */
124
+ export function fingerprintQuery(raw) {
125
+ const semantic = {
126
+ from: raw['from'],
127
+ join: raw['join'],
128
+ select: raw['select'],
129
+ where: raw['where'],
130
+ orderBy: raw['orderBy'],
131
+ groupBy: raw['groupBy'],
132
+ agg: raw['agg'],
133
+ };
134
+ const json = JSON.stringify(canonicalize(semantic));
135
+ return fnv1a(utf8Bytes(json)).toString(16).padStart(8, '0');
136
+ }
137
+ function encodePayload(payload) {
138
+ const json = JSON.stringify(payload);
139
+ return hexOf(utf8Bytes(json)) + '.' + checksumOf(json);
140
+ }
141
+ function decodePayload(token) {
142
+ const dot = token.lastIndexOf('.');
143
+ if (dot <= 0 || dot === token.length - 1) {
144
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(须为 载荷.校验 两段)');
145
+ }
146
+ const hex = token.slice(0, dot);
147
+ const sum = token.slice(dot + 1);
148
+ if (!/^[0-9a-fA-F]{8}$/.test(sum)) {
149
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(校验段须为 8 位十六进制)');
150
+ }
151
+ let json;
152
+ try {
153
+ json = utf8String(bytesOfHex(hex));
154
+ }
155
+ catch {
156
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(载荷解不开)');
157
+ }
158
+ let payload;
159
+ try {
160
+ payload = JSON.parse(json);
161
+ }
162
+ catch {
163
+ fail('DATA_QUERY_INVALID', '续取凭据无效:格式错误(载荷不是 JSON)');
164
+ }
165
+ if (checksumOf(json).toLowerCase() !== sum.toLowerCase()) {
166
+ fail('DATA_QUERY_INVALID', '续取凭据无效:校验未通过(可能被篡改或乱填,请从第一页重取)');
167
+ }
168
+ if (!isRecord(payload))
169
+ fail('DATA_QUERY_INVALID', '续取凭据无效:载荷须为对象');
170
+ const rec = payload;
171
+ if (rec['v'] !== TOKEN_VERSION) {
172
+ fail('DATA_QUERY_INVALID', '续取凭据无效:版本不认(实际:' + String(rec['v']) + ')');
173
+ }
174
+ return rec;
175
+ }
176
+ /** 行查询凭据编码(游标:排序列值 + `rowid` 系链;值原样进 JSON,`NULL` 即 `null`)。 */
177
+ export function encodeRowToken(fingerprint, orderingValues, rowids) {
178
+ const payload = { v: TOKEN_VERSION, k: 'r', f: fingerprint, c: { o: [...orderingValues], r: [...rowids] } };
179
+ return encodePayload(payload);
180
+ }
181
+ /** 行查询凭据解码(种类/指纹/形状逐项验,错即按项拒,报文可读)。 */
182
+ export function decodeRowToken(token, expectedFingerprint, expectedOrderLen, expectedRowidLen) {
183
+ const payload = decodePayload(token);
184
+ if (payload.k !== 'r') {
185
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询类型不匹配(行查询/聚合查询各走各的凭据,不可混用)');
186
+ }
187
+ const row = payload;
188
+ if (row.f !== expectedFingerprint) {
189
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询单不匹配(from/join/select/where/orderBy 改动后须从第一页重取)');
190
+ }
191
+ if (!isRecord(row.c))
192
+ fail('DATA_QUERY_INVALID', '续取凭据无效:游标须为对象');
193
+ const c = row.c;
194
+ if (!Array.isArray(c.o) || !Array.isArray(c.r)) {
195
+ fail('DATA_QUERY_INVALID', '续取凭据无效:游标形状错误(须含排序值与行号两段)');
196
+ }
197
+ if (c.o.length !== expectedOrderLen) {
198
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询单不匹配(排序列数变了,须从第一页重取)');
199
+ }
200
+ if (c.r.length !== expectedRowidLen) {
201
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询单不匹配(连接形状变了,须从第一页重取)');
202
+ }
203
+ for (const r of c.r) {
204
+ if ((typeof r !== 'number' || !Number.isInteger(r)) && r !== null) {
205
+ fail('DATA_QUERY_INVALID', '续取凭据无效:行号须为整数');
206
+ }
207
+ }
208
+ return { orderingValues: [...c.o], rowids: [...c.r] };
209
+ }
210
+ /** 聚合查询凭据编码(偏移:已跳过多少组;端到端待 #957 聚合落地后接线)。 */
211
+ export function encodeAggToken(fingerprint, offset) {
212
+ if (!Number.isInteger(offset) || offset < 0) {
213
+ fail('DATA_QUERY_INVALID', '续取凭据无效:偏移须为非负整数');
214
+ }
215
+ const payload = { v: TOKEN_VERSION, k: 'a', f: fingerprint, o: offset };
216
+ return encodePayload(payload);
217
+ }
218
+ /** 聚合查询凭据解码(种类/指纹/偏移逐项验,错即按项拒)。 */
219
+ export function decodeAggToken(token, expectedFingerprint) {
220
+ const payload = decodePayload(token);
221
+ if (payload.k !== 'a') {
222
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询类型不匹配(行查询/聚合查询各走各的凭据,不可混用)');
223
+ }
224
+ const agg = payload;
225
+ if (agg.f !== expectedFingerprint) {
226
+ fail('DATA_QUERY_INVALID', '续取凭据无效:与查询单不匹配(from/where/groupBy/agg 改动后须从第一页重取)');
227
+ }
228
+ if (typeof agg.o !== 'number' || !Number.isInteger(agg.o) || agg.o < 0) {
229
+ fail('DATA_QUERY_INVALID', '续取凭据无效:偏移须为非负整数');
230
+ }
231
+ return agg.o;
232
+ }
233
+ function ident(name) {
234
+ return '"' + name.replace(/"/g, '""') + '"';
235
+ }
236
+ function colRef(table, column) {
237
+ return table === null ? ident(column) : ident(table) + '.' + ident(column);
238
+ }
239
+ function rowidRef(table) {
240
+ return table === null ? 'rowid' : ident(table) + '.rowid';
241
+ }
242
+ /**
243
+ * 游标条件(`ORDER BY` 全序的“下一页”:元组大于上一页末行,`NULL` 安全)。
244
+ * `ASC`(`NULL` 居首):末值 `NULL` → 后继为非 `NULL`;末值非 `NULL` → 后继为更大值。
245
+ * `DESC`(`NULL` 居尾):末值 `NULL` → 本列无后继(靠系链);末值非 `NULL` → 后继为更小值或 `NULL`。
246
+ * 系链(`rowid ASC`):后继恒为更大行号。
247
+ * 返回不带 `WHERE` 关键字的片段,调用方与用户条件按 `AND` 拼。
248
+ */
249
+ export function buildCursorCondition(orders, rowids) {
250
+ const units = [
251
+ ...orders.map((o) => ({ dir: o.dir, last: o.lastValue, ref: colRef(o.table, o.column), isRowid: false })),
252
+ ...rowids.map((r) => ({ dir: 'ASC', last: r.lastRowid, ref: rowidRef(r.table), isRowid: true })),
253
+ ];
254
+ const branches = [];
255
+ const params = [];
256
+ for (let i = 0; i < units.length; i += 1) {
257
+ const cur = units[i];
258
+ let greater = null;
259
+ let greaterParam = [];
260
+ if (cur.isRowid) {
261
+ if (cur.last === null) {
262
+ greater = cur.ref + ' IS NOT NULL';
263
+ }
264
+ else {
265
+ greater = cur.ref + ' > ?';
266
+ greaterParam = [cur.last];
267
+ }
268
+ }
269
+ else if (cur.dir === 'ASC') {
270
+ if (cur.last === null) {
271
+ greater = cur.ref + ' IS NOT NULL';
272
+ }
273
+ else {
274
+ greater = cur.ref + ' > ?';
275
+ greaterParam = [cur.last];
276
+ }
277
+ }
278
+ else {
279
+ if (cur.last === null) {
280
+ greater = null;
281
+ }
282
+ else {
283
+ greater = '(' + cur.ref + ' < ? OR ' + cur.ref + ' IS NULL)';
284
+ greaterParam = [cur.last];
285
+ }
286
+ }
287
+ if (greater === null)
288
+ continue;
289
+ const prefix = [];
290
+ for (let j = 0; j < i; j += 1) {
291
+ const prev = units[j];
292
+ if (prev.last === null) {
293
+ prefix.push(prev.ref + ' IS NULL');
294
+ }
295
+ else {
296
+ prefix.push(prev.ref + ' = ?');
297
+ params.push(prev.last);
298
+ }
299
+ }
300
+ params.push(...greaterParam);
301
+ if (prefix.length === 0) {
302
+ branches.push('(' + greater + ')');
303
+ }
304
+ else {
305
+ branches.push('(' + prefix.join(' AND ') + ' AND ' + greater + ')');
306
+ }
307
+ }
308
+ if (branches.length === 0) {
309
+ fail('DATA_INTERNAL', '游标条件装配失败(排序与系链均为空)');
310
+ }
311
+ return { sql: branches.join(' OR '), params };
312
+ }
313
+ //# sourceMappingURL=data-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-page.js","sourceRoot":"","sources":["../src/data-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,sCAAsC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,sCAAsC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,+CAA+C;AAC/C,MAAM,SAAS,GAAG,oBAAoB,CAAC;AAEvC,0BAA0B;AAC1B,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,SAAS,IAAI,CAAC,IAAY,EAAE,OAAe;IACzC,MAAM,IAAI,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,QAAQ,CAAC,OAAgB,EAAE,IAAY;IACrD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,2BAA2B,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,SAAS,YAAY,CAAC,OAAgB,EAAE,IAAY;IAClD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,iBAAiB,CAAC;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,oBAAoB,GAAG,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAC/G,CAAC;IACD,MAAM,IAAI,GAAG,OAAiB,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;QACrC,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,oBAAoB,GAAG,aAAa,GAAG,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,OAAgB,EAAE,IAAY;IAClD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,sCAAsC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAAiB,CAAC;AAC3B,CAAC;AAED,uDAAuD;AACvD,SAAS,YAAY,CAAC,CAAU;IAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAQ,CAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAChE,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAA4B,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACjE,MAAM,IAAI,GAAI,CAA6B,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,CAAa;IAC/B,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,oCAAoC;AACpC,SAAS,KAAK,CAAC,KAAiB;IAC9B,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,CAAC,IAAI,IAAI,CAAC;QACV,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,KAAK,CAAC,KAAiB;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC;QACrD,CAAC;QACD,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,WAAmB;IACrC,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAA4B;IAC3D,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC;QACjB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;QACnB,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC;QACvB,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC;QACvB,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC;KAChB,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAgBD,SAAS,aAAa,CAAC,OAAgC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,oBAAoB,EAAE,0BAA0B,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC,oBAAoB,EAAE,4BAA4B,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAc,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,UAAU,CAAC,IAAc,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;QACnE,IAAI,CAAC,oBAAoB,EAAE,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,aAAa,EAAE,CAAC;QAC/B,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,GAAyC,CAAC;AACnD,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,cAAkC,EAClC,MAAgC;IAEhC,MAAM,OAAO,GAAe,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,EAAE,CAAC;IACxH,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,mBAA2B,EAC3B,gBAAwB,EACxB,gBAAwB;IAExB,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAK,OAAsB,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,oBAAoB,EAAE,sCAAsC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,GAAG,GAAG,OAAqB,CAAC;IAClC,IAAI,GAAG,CAAC,CAAC,KAAK,mBAAmB,EAAE,CAAC;QAClC,IAAI,CACF,oBAAoB,EACpB,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAY,CAAC;QAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IAC7E,MAAM,CAAC,GAAG,GAAG,CAAC,CAA+B,CAAC;IAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,oBAAoB,EAAE,2BAA2B,CAAC,CAAC;IAC1D,CAAC;IACD,IAAK,CAAC,CAAC,CAAe,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACnD,IAAI,CAAC,oBAAoB,EAAE,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAK,CAAC,CAAC,CAAe,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACnD,IAAI,CAAC,oBAAoB,EAAE,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAc,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAClE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,CAAC,GAAI,CAAC,CAAC,CAAe,CAAC,EAAE,MAAM,EAAE,CAAC,GAAI,CAAC,CAAC,CAAqB,CAAC,EAAE,CAAC;AAC5F,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,MAAc;IAChE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,OAAO,GAAe,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACpF,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,mBAA2B;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAK,OAAsB,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACtC,IAAI,CAAC,oBAAoB,EAAE,sCAAsC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,GAAG,GAAG,OAAqB,CAAC;IAClC,IAAI,GAAG,CAAC,CAAC,KAAK,mBAAmB,EAAE,CAAC;QAClC,IAAI,CACF,oBAAoB,EACpB,mDAAmD,CACpD,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAK,GAAG,CAAC,CAAY,GAAG,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,GAAG,CAAC,CAAW,CAAC;AACzB,CAAC;AAgBD,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC;AAC9C,CAAC;AAED,SAAS,MAAM,CAAC,KAAoB,EAAE,MAAc;IAClD,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,QAAQ,CAAC,KAAoB;IACpC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkC,EAClC,MAAkC;IAGlC,MAAM,KAAK,GAAW;QACpB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAc,EAAE,CAAC,CAAC;QAClH,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAc,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAa,EAAE,CAAC,CAAC;KACnH,CAAC;IACF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,IAAI,YAAY,GAA+B,EAAE,CAAC;QAClD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC;gBAC3B,YAAY,GAAG,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC;gBAC3B,YAAY,GAAG,CAAC,GAAG,CAAC,IAA8B,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,WAAW,CAAC;gBAC7D,YAAY,GAAG,CAAC,GAAG,CAAC,IAA8B,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,IAAI,OAAO,KAAK,IAAI;YAAE,SAAS;QAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAA8B,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,108 @@
1
+ /** 绑定参数只用这三种(布尔在装配时已转 0/1,不进绑定)。 */
2
+ export type DataQueryParam = string | number | null;
3
+ /** 库句柄的最小形状:只用到 `prepare(sql).all(...params)`。 */
4
+ export interface DataQueryDb {
5
+ prepare(sql: string): {
6
+ all(...params: DataQueryParam[]): unknown[];
7
+ };
8
+ }
9
+ /** 叶子条件:字段+操作符+值(`isNull`/`isNotNull` 不带值,`in` 带数组)。 */
10
+ export interface DataCondition {
11
+ readonly field: string;
12
+ readonly op: string;
13
+ readonly value?: DataQueryParam | readonly DataQueryParam[] | boolean;
14
+ }
15
+ /** 条件组:`and`/`or` 恰居其一,内含条件或嵌套组。 */
16
+ export interface DataWhereGroup {
17
+ readonly and?: readonly DataQueryWhere[];
18
+ readonly or?: readonly DataQueryWhere[];
19
+ }
20
+ /** 条件树:叶子或组(可嵌套)。 */
21
+ export type DataQueryWhere = DataCondition | DataWhereGroup;
22
+ /** 排序项:字段+方向(`asc`/`desc`,大小写不敏感)。 */
23
+ export interface DataOrderBy {
24
+ readonly field: string;
25
+ readonly dir: string;
26
+ }
27
+ /** 单张查询单:表+选列+条件+排序(`id` 原样回显;`join` 见 #956 连接一支;`groupBy`+`agg` 见 #957 分组聚合一支;`page` 见 #958 分页续取一支)。 */
28
+ export interface DataQuery {
29
+ readonly id?: string;
30
+ readonly from: string;
31
+ readonly join?: readonly DataJoin[];
32
+ readonly select?: readonly string[];
33
+ readonly where?: DataQueryWhere;
34
+ readonly groupBy?: readonly string[];
35
+ readonly agg?: readonly DataAgg[];
36
+ readonly orderBy?: readonly DataOrderBy[];
37
+ readonly page?: DataPage;
38
+ }
39
+ /** 分页输入:页大小与续取凭据(`next` 由上一次结果回传,首页传 `null`/缺席)。 */
40
+ export interface DataPage {
41
+ readonly size?: number;
42
+ readonly next?: string | null;
43
+ }
44
+ /** 聚合项:函数+被聚合列+输出名(`as` 即结果集 `fields` 里该列的名字)。
45
+ *
46
+ * `fn` 为 `sum`/`avg`/`count`/`min`/`max`(大小写不敏感);
47
+ * `field` 为裸列名,唯 `count` 允许 `"*"`(计行数,其余 `count(列)` 计非空);
48
+ * `as` 为输出名:非空、聚合内唯一、不得与该表任何列同名(防遮蔽)。
49
+ */
50
+ export interface DataAgg {
51
+ readonly fn: string;
52
+ readonly field: string;
53
+ readonly as: string;
54
+ }
55
+ /** 连接条件里的一对相等(左右皆为 `表.列` 限定引用,且恰好跨两表)。 */
56
+ export interface DataJoinOn {
57
+ readonly left: string;
58
+ readonly right: string;
59
+ }
60
+ /** 一次连接(本票只做两表:`join` 数组长度只许 1)。
61
+ *
62
+ * `type` 须显式写(`inner`/`left`,大小写不敏感),无缺省;
63
+ * `on` 为显式连接条件(非空数组,多对按 AND 拼);
64
+ * `via` 预定义关联路径只留语法位——出现即按项拒(后续加法式扩,本票不实现)。
65
+ */
66
+ export interface DataJoin {
67
+ readonly table: string;
68
+ readonly type: string;
69
+ readonly on: readonly DataJoinOn[];
70
+ readonly via?: unknown;
71
+ }
72
+ /** 批量请求:查询单数组(与结果一一对应、同序,见规格 §四①)。 */
73
+ export interface DataQueriesRequest {
74
+ readonly queries: readonly DataQuery[];
75
+ }
76
+ /** 结果列:名与 SQLite 声明类型原文(与目录命令同一份)。 */
77
+ export interface DataField {
78
+ readonly name: string;
79
+ readonly type: string;
80
+ }
81
+ /** 成功项:回显查询单,行以「列名→值」的对象给(含 `NULL` 即 `null`);`total` 为全量命中数,`next` 只在还有后页时回(末页不回,见 #958)。 */
82
+ export interface DataSuccessItem {
83
+ readonly id?: string;
84
+ readonly ok: true;
85
+ readonly query: DataQuery;
86
+ readonly fields: readonly DataField[];
87
+ readonly rows: readonly Record<string, unknown>[];
88
+ readonly total: number;
89
+ readonly next?: string;
90
+ }
91
+ /** 失败项:坏项带错误、好项照常(单项失败不毁整批,见规格 §四②)。 */
92
+ export interface DataErrorItem {
93
+ readonly id?: string;
94
+ readonly ok: false;
95
+ readonly query: unknown;
96
+ readonly error: {
97
+ readonly code: string;
98
+ readonly message: string;
99
+ };
100
+ }
101
+ export type DataResultItem = DataSuccessItem | DataErrorItem;
102
+ /**
103
+ * 跑一批查询单:请求级非法(不是对象/`queries` 不是非空数组)即抛;
104
+ * 单项的表/字段/形状/执行问题收进那一项的 `{ ok: false, error }`,其余项照常。
105
+ * 返回与请求同序对应的 `results`(调用方按此装 envelope)。
106
+ */
107
+ export declare function executeDataQueries(db: DataQueryDb, allowTables: readonly string[], request: unknown): DataResultItem[];
108
+ //# sourceMappingURL=data-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-query.d.ts","sourceRoot":"","sources":["../src/data-query.ts"],"names":[],"mappings":"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"}