@lunora/sql-store 1.0.0-alpha.102 → 1.0.0-alpha.103
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/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSqlCtxDb as a,readSqlCdcChangedTables as o,readSqlCdcChanges as t,readSqlCdcFloor as l,runSqlAggregateMigrations as n,runSqlCdcMigration as s,runSqlGlobalTableMigrations as i,runSqlRankMigrations as d,sweepSqlCdcRetention as S}from"./packem_shared/createSqlCtxDb-
|
|
1
|
+
import{createSqlCtxDb as a,readSqlCdcChangedTables as o,readSqlCdcChanges as t,readSqlCdcFloor as l,runSqlAggregateMigrations as n,runSqlCdcMigration as s,runSqlGlobalTableMigrations as i,runSqlRankMigrations as d,sweepSqlCdcRetention as S}from"./packem_shared/createSqlCtxDb-B9-Pge3V.mjs";import{d as q,r as g}from"./packem_shared/ctx-db-search-BiMTuJzw.mjs";import{SEARCH_STATE_TABLE as f,migrateSearchState as m}from"./packem_shared/SEARCH_STATE_TABLE-B5a5xBwB.mjs";import{c as b,e as p,a as u,s as h,t as M}from"./packem_shared/value-codec-CwTLrqfU.mjs";import{decodeGlobalRow as A}from"./packem_shared/decodeGlobalRow-C8O2hy0d.mjs";export{f as SEARCH_STATE_TABLE,q as backfillSqlSearchIndexes,a as createSqlCtxDb,b as decodeBigint,A as decodeGlobalRow,p as effectiveColumnKind,m as migrateSearchState,o as readSqlCdcChangedTables,t as readSqlCdcChanges,l as readSqlCdcFloor,n as runSqlAggregateMigrations,s as runSqlCdcMigration,i as runSqlGlobalTableMigrations,d as runSqlRankMigrations,g as runSqlSearchMigrations,u as sqliteDecode,h as sqliteEncode,S as sweepSqlCdcRetention,M as tryJsonParse};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{LunoraError as g}from"@lunora/errors";import{c as Ct,r as At,A as Lt,q as Nt,C as kt,R as Mt,a as Dt,T as qt,x as Ot,b as Ft}from"./ctx-db-search-BiMTuJzw.mjs";import{d as oi}from"./ctx-db-search-BiMTuJzw.mjs";import{literalInList as Bt,throwingScheduler as xt,CDC_LOG_TABLE as G,cursorBelowRetainedFloor as Wt,cdcTrimmedError as Ut,aggregateTableName as J,rankTableName as ne,assertNoExplicitUndefined as Ze,hasTrigger as Pt,runRowValidators as De,assertFlatPredicate as et,mergeWhere as O,sortColumnName as Q,resolveRankPartition as tt,encodePartitionKey as Ce,resolveRankSeekTuple as jt,RANK_TIEBREAK as Ee,CountRlsUnsupportedError as nt,normalizeIdStructurally as Kt,assertValidClientId as Ht,aggregateSqlFunction as we,softDeleteScope as _e,compileWhereSql as $e,normalizeOrderKeys as Gt,buildSeekWhere as Vt,decodeCursor as Yt,resolveRelationPredicates as it,resolveWith as ot,relationHooks as rt,applySelect as st,encodeCursor as Xt,NotFoundError as zt,applyOnDelete as Jt,ConflictError as he,normalizeCountArgument as Qt,selectIndexForCount as Zt,encodeAggregateKey as z,selectIndexForAggregate as en,readAggregateValue as qe,runTriggers as tn,matchesRankStaticWhere as at,CURSOR_PREFIX as nn,selectIndexForGroupBy as on,tiebreakDirectionFor as rn,fanOutScalarCounts as sn,matchesStaticWhere as Oe,foldAggregateTally as an,coerceAggregateNumber as Fe,CDC_LOG_TABLE_SEQ_INDEX as cn,NotUniqueError as dn}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{d as _t,e as Le,n as ln,b as un}from"./value-codec-CwTLrqfU.mjs";import{migrateSearchState as fn}from"./SEARCH_STATE_TABLE-B5a5xBwB.mjs";import{queryAll as I,queryRun as A,createIndexIfNotExists as Ae,decodeRow as ie,serializeColumnValue as H,columnRefSql as F,decodeRows as wn,forEachRowPaged as ct,queryBatch as dt}from"./decodeGlobalRow-C8O2hy0d.mjs";import{decodeGlobalRow as si}from"./decodeGlobalRow-C8O2hy0d.mjs";const _n=(s,l)=>{if(s.size<l)return;const u=s.keys().next().value;u!==void 0&&s.delete(u)},lt=50,$n=(s,l={})=>{const u=l.maxBatch??lt,i=Number.isInteger(u)&&u>0?u:lt,h=new Map;let d=!1;const c=async(R,b)=>{const v=[...b.keys()];for(let L=0;L<v.length;L+=i){const M=v.slice(L,L+i);try{const x=await s(R,M);for(const V of M){const Y=x.get(V);for(const X of b.get(V)??[])X.resolve(Y)}}catch(x){for(const V of M)for(const Y of b.get(V)??[])Y.reject(x)}}},m=()=>{d=!1;const R=[...h.entries()];h.clear();for(const[b,v]of R)c(b,v).catch(()=>{})};return{async load(R,b){return new Promise((v,L)=>{let M=h.get(R);M||(M=new Map,h.set(R,M));const x=M.get(b);x?x.push({reject:L,resolve:v}):M.set(b,[{reject:L,resolve:v}]),d||(d=!0,queueMicrotask(m))})}}},hn=new Set(["_id","id"]),We=(s,l,u)=>s==="postgres"?e`${l} IS NOT DISTINCT FROM ${u}`:s==="mysql"?e`${l} <=> ${u}`:e`${l} IS ${u}`,En=(s,l)=>s.name!=="postgres"||l.nullable!==!0?"":l.direction==="desc"?" NULLS LAST":" NULLS FIRST",yn=(s,l)=>{const u=s.map(i=>e`${F(i.field)} ${e.raw(`${i.direction==="desc"?"DESC":"ASC"}${En(l,i)}`)}`);if(!s.some(i=>hn.has(i.field))){const i=rn(s);u.push(e`${F("id")} ${e.raw(i==="desc"?"DESC":"ASC")}`)}return e.join(u,e`, `)},ut=50,Ue=s=>{const l=[];for(const[u,i]of Object.entries(s.shape)){const h=i._meta?.column;h&&l.push([u,h])}return l},pn=(s,l,u)=>{const i={...l};for(const[h,d]of Ue(s)){if(d.serverDefault){i[h]=d.serverDefault({auth:u});continue}i[h]===void 0&&(d.defaultFn?i[h]=d.defaultFn():"defaultValue"in d&&(i[h]=d.defaultValue))}return i},ft=(s,l,u,i)=>{for(const[h,d]of Ue(s)){if(d.serverDefault){h in l&&(u[h]=d.serverDefault({auth:i}));continue}d.onUpdateFn&&!(h in l)&&(u[h]=d.onUpdateFn())}},Rn=128,Tn=()=>{const s=new Map;return{delete:l=>{s.delete(l)},get:l=>{const u=s.get(l);if(u!==void 0)return s.delete(l),s.set(l,u),u},set:(l,u)=>{s.has(l)?s.delete(l):_n(s,Rn),s.set(l,u)}}},mn=async(s,l,u,i,h)=>{const d=h.get(i);if(d!==void 0)return d;const c=Object.entries(u.tables).filter(([,R])=>R.shardMode===void 0||R.shardMode.kind==="global").map(([R])=>R),m=await Promise.all(c.map(async R=>({found:(await I(s,l,e`SELECT 1 FROM ${e.identifier(R)} WHERE ${e.identifier("id")} = ${i} LIMIT 1`)).length>0,tableName:R})));for(const R of m)if(R.found)return h.set(i,R.tableName),R.tableName},oe=s=>s==null?null:Number(s),Sn=(s,l)=>l.map(u=>{const i={};for(const h of s)i[h]=u[h]??null;return{key:i,value:oe(u.value)}}),gn=(s,l,u)=>[...s.partitionBy??[],...s.sortBy.map(h=>h.field),...s.where?Object.keys(s.where):[]].every(h=>l[h]===u[h]),$t=s=>s.length===1?s[0]:e`(${e.join(s,e` AND `)})`,te=s=>e.join(s.map(l=>e`${e.identifier(l)}`),e`, `),re=s=>e.join(s.map(l=>e`${l}`),e`, `),vn=(s,l,u,i,h)=>{const d=[];for(let c=0;c<u.length+1;c+=1){const m=u.slice(0,c).map(v=>We(s,e`${e.identifier(v)}`,i[v])),R=u[c],b=l.sortBy[c];c<u.length&&R!==void 0&&b!==void 0?m.push(e`${e.identifier(R)} ${e.raw(b.direction==="desc"?">":"<")} ${i[R]}`):m.push(e`${e.identifier(Ee)} < ${h}`),d.push($t(m))}return d.length>0?e.join(d,e` OR `):void 0},bn=(s,l,u)=>{if(u.length!==l.length)return;const i=[];for(const[h,d]of l.entries()){const c=[];for(let m=0;m<h;m+=1){const R=l[m];R!==void 0&&c.push(We(s,e`${e.identifier(R.column)}`,u[m]))}c.push(e`${e.identifier(d.column)} ${e.raw(d.direction==="desc"?"<":">")} ${u[h]}`),i.push($t(c))}return e`(${e.join(i,e` OR `)})`},In=(s,l)=>{if(s.sortBy.length===0)throw new g("INTERNAL",`rankIndex "${s.name}" requires at least one "sortBy" column for stable pagination`);const u=[{column:"__partition__",direction:"asc"}];for(const[i,h]of s.sortBy.entries())u.push({column:l[i]??Q(i),direction:h.direction});return u.push({column:Ee,direction:"asc"}),u},Cn=async(s,l,u,i,h)=>{const c=[];for(let v=0;v<h.length;v+=50)c.push(h.slice(v,v+50));const m=await Promise.all(c.map(async v=>I(s,l,e`SELECT * FROM ${e.identifier(i)} WHERE ${e.identifier("id")} IN (${re(v)})`))),R=new Map;for(const v of m)for(const L of v)R.set(L.id,L);const b=[];for(const v of h){const L=ie(u,R.get(v));L&&b.push(L)}return b},An=s=>{const l=JSON.stringify(s),u=new TextEncoder().encode(l);let i="";for(const h of u)i+=String.fromCodePoint(h);return nn+btoa(i)},Ln=(s,l)=>l.columnType(Le(s)),Nn=(s,l,u)=>{const i=[];for(const[c,m]of Object.entries(l.shape)){if(!m._meta?.column)continue;const R=m._meta.column.notNull&&m.kind!=="optional"?" NOT NULL":"";i.push(e`${e.identifier(c)} ${e.raw(`${Ln(m,u)}${R}`)}`)}const h=u.frameworkColumns().map(c=>e`${e.identifier(c.name)} ${e.raw(c.type)}`),d=h.length+i.length;if(u.maxTableColumns!==void 0&&d>u.maxTableColumns)throw new g("VALIDATION_ERROR",`@lunora/sql-store: global table "${s}" needs ${String(d)} columns, over this engine's ${String(u.maxTableColumns)}-column limit — split the table, or move the extra fields into one object field`);return e.join([...h,...i],e`, `)},kn=async(s,l,u,i)=>{const h=d=>{const c=F(d),m=u.shape[d],R=m&&i.indexKeyPrefix?i.indexKeyPrefix(Le(m)):void 0;return R===void 0?c:e`${c}(${e.raw(String(R))})`};for(const d of u.indexes){const c=e.join(d.fields.map(m=>h(m)),e`, `);await Ae(s,i,{columns:c,name:`${l}_${d.name}`,table:l,unique:d.unique??!1})}for(const[d,c]of Ue(u))c.unique&&await Ae(s,i,{columns:h(d),name:`${l}_unique_${d}`,table:l,unique:!0})},Mn=async(s,l,u)=>{for(const[i,h]of Object.entries(l.tables)){if(h.shardMode?.kind!=="global")continue;const d=Nn(i,h,u);await A(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(i)} (${d})`),await kn(s,i,h,u)}},Dn=async(s,l,u)=>{const{integer:i,key:h,real:d}=u.companionTypes;for(const[c,m]of Object.entries(l.tables)){const R=m.aggregateIndexes;if(!(!R||R.length===0))for(const b of R){const v=J(c,b.name);await A(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(v)} (${e.identifier("__key__")} ${e.raw(h)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(d)}, ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0)`),u.name==="sqlite"&&((await I(s,u,e`PRAGMA table_info(${e.identifier(v)})`)).some(M=>M.name==="__count__")||await A(s,u,e`ALTER TABLE ${e.identifier(v)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0`))}}},Be=(s,l,u,i)=>{const h=s.name==="mysql"&&i?e`${e.identifier(l)}(191)`:e`${e.identifier(l)}`;return e`${h} ${e.raw(u)}`},qn=(s,l,u)=>{const i=[Be(s,"__partition__","ASC",!0)];for(const[h,d]of l.sortBy.entries()){const c=u.shape[d.field],m=c!==void 0&&s.indexKeyPrefix?.(Le(c))!==void 0;i.push(Be(s,Q(h),d.direction==="desc"?"DESC":"ASC",m))}return i.push(Be(s,"__id__","ASC",!0)),i},On=(s,l,u)=>l.sortBy.map((i,h)=>{const d=u.shape[i.field],c=s.columnType(d?Le(d):void 0);return e`${e.identifier(Q(h))} ${e.raw(c)}`}),Fn=async(s,l,u)=>{const{key:i}=u.companionTypes;for(const[h,d]of Object.entries(l.tables)){const c=d.rankIndexes;if(!(!c||c.length===0))for(const m of c){const R=ne(h,m.name),b=On(u,m,d),v=b.length>0?e`, ${e.join(b,e`, `)}`:e``;await A(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(R)} (${e.identifier("__id__")} ${e.raw(i)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(i)} NOT NULL${v})`);const L=qn(u,m,d),M=`${h}__rank_${m.name}__btree`;await Ae(s,u,{columns:e.join(L,e`, `),name:M,table:R,unique:!1})}}},xe="__cdc_sweep",ht="global",Bn=6e4,xn=1e4,Wn=3e4;let wt=0;const Un=async(s,l)=>{const{autoincrementPrimaryKey:u,key:i,real:h,text:d}=l.companionTypes;await A(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(G)} (${e.identifier("seq")} ${e.raw(u)}, ${e.identifier("ts")} ${e.raw(h)} NOT NULL, ${e.identifier("table")} ${e.raw(i)} NOT NULL, ${e.identifier("id")} ${e.raw(i)} NOT NULL, ${e.identifier("op")} ${e.raw(i)} NOT NULL, ${e.identifier("doc")} ${e.raw(d)})`);const c=l.indexKeyPrefix?.("string");await Ae(s,l,{columns:e`${c===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(c))})`}, ${e.identifier("seq")}`,name:cn,table:G,unique:!1}),await A(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(xe)} (${e.identifier("id")} ${e.raw(i)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(h)} NOT NULL)`),await A(s,l,e`INSERT INTO ${e.identifier(xe)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${ht}, ${0}) ${l.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},Pn=async(s,l,u)=>{const i=e`UPDATE ${e.identifier(xe)} SET ${e.identifier("lease_until")} = ${u+Bn} WHERE ${e.identifier("id")} = ${ht} AND ${e.identifier("lease_until")} <= ${u}`;if(l.supportsReturning)return(await I(s,l,e`${i} RETURNING ${e.identifier("id")}`)).length>0;const h=await A(s,l,i);return(l.affectedRows?l.affectedRows(h??{rowsAffected:0}):0)>0},jn=async(s,l,u,i)=>{if(!await Pn(s,l,i))return;const h=i-u;await A(s,l,e`
|
|
2
|
+
DELETE FROM ${e.identifier(G)} WHERE ${e.identifier("seq")} IN (
|
|
3
|
+
SELECT ${e.identifier("seq")} FROM (
|
|
4
|
+
SELECT ${e.identifier("seq")} FROM ${e.identifier(G)} WHERE ${e.identifier("ts")} <= ${h} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(xn))}
|
|
5
|
+
) AS ${e.identifier("expired")}
|
|
6
|
+
)
|
|
7
|
+
`)},Et=async(s,l)=>{const u=await I(s,l,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(G)}`),i=Number(u[0]?.seq??Number.NaN);return Number.isFinite(i)?i:void 0},Kn=s=>JSON.stringify(ln(s)?un(s):s),Hn=async(s,l,u,i,h,d,c)=>{await A(s,c,e`INSERT INTO ${e.identifier(G)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${l}, ${u}, ${i}, ${h}, ${d===void 0?null:Kn(d)})`)},ei=async(s,l,u)=>{const i=l.sinceSeq??0,h=Math.max(1,Math.min(l.limit??1e3,1e4)),d=await Et(s,u);if(d!==void 0&&Wt(d,i))throw Ut(d,i,"global");const m=(await I(s,u,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(G)} WHERE seq > ${i} ORDER BY seq ASC LIMIT ${e.raw(String(h))}`)).map(R=>{const{doc:b}=R,v={id:String(R.id),op:String(R.op),seq:Number(R.seq),table:String(R.table),ts:Number(R.ts)};return typeof b=="string"?{...v,doc:_t(JSON.parse(b))}:v});return{changes:m,cursor:m.at(-1)?.seq??i}},Gn=async(s,l,u,i={})=>{if(i.cursorOnly){const R=await I(s,u,e`SELECT MAX(seq) AS seq FROM ${e.identifier(G)}`),b=Number(R[0]?.seq??l);return{cursor:Number.isFinite(b)?b:l,tables:[]}}const h=await I(s,u,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(G)} WHERE seq > ${l} GROUP BY ${e.identifier("table")}`);let d=l;const c=[];for(const R of h){const b=Number(R.seq);Number.isFinite(b)&&b>d&&(d=b),c.push(String(R.table))}const m=i.retained===!0?await Et(s,u):void 0;return{cursor:d,tables:c,...m===void 0?{}:{floor:m}}},ti=s=>{const{crossShardCounter:l,crossShardReader:u,exec:i,maxRelationKeys:h,schema:d}=s,{dialect:c}=s,{isUniqueViolation:m}=c,R={fieldRef:F,serialize:H,...c.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...c.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...c.name==="sqlite"?{}:{inList:Bt}},b=(t,n)=>We(c.name,t,n),v=t=>{const n=te(t.columns),o=re(t.values),r=f=>c.name==="mysql"?e`VALUES(${e.identifier(f)})`:e`excluded.${e.identifier(f)}`,a=f=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(f)}`:e`${e.identifier(f)}`,_=e.join(Object.entries(t.set(r,a)).map(([f,y])=>e`${e.identifier(f)} = ${y}`),e`, `),E=c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${_}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${_}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${o}) ${E}`},L=s.clock??(()=>Date.now()),M=s.idGenerator??(()=>crypto.randomUUID()),x=s.cdc??!1,V=typeof s.cdcRetentionMs=="number"&&Number.isFinite(s.cdcRetentionMs)&&s.cdcRetentionMs>0?s.cdcRetentionMs:void 0,Y=s.auth??{identity:null,userId:null},X=async(t,n,o,r)=>{if(!x||(await Hn(i,L(),t,n,o,r,c),V===void 0))return;const a=L();if(!(a-wt<Wn)){wt=a;try{await jn(i,c,V,a)}catch{}}},yt=s.scheduler??xt,Ne=Tn();let ye=0,ke;const W=async()=>(ke??=(async()=>{await Mn(i,d,c),await Dn(i,d,c),await Fn(i,d,c),await fn(i,c),await At(i,d,c),x&&await Un(i,c)})().catch(t=>{throw ke=void 0,t}),ke),se=async(t,n)=>{await W();const o=await mn(i,c,d,t,Ne);if(!(n!==void 0&&o!==n))return o},ae=new Map,Pe=async(t,n)=>{const o=J(t,n);return(await I(i,c,c.tableExists(o))).length>0},pe=async(t,n)=>{const o=`${t}::${n.name}`,r=ae.get(o);if(r!==void 0)return r;if(!await Pe(t,n.name))return ae.set(o,!1),!1;const _=d.tables[t];if(!_)return ae.set(o,!1),!1;const E=n.by??[],f=new Map;await ct(i,c,_,t,$=>{if(n.where&&!Oe($,n.where))return;const p=z(E,$);an(f,p,n,$)});const y=J(t,n.name);await A(i,c,e`DELETE FROM ${e.identifier(y)}`);const w=[];for(const[$,p]of f)w.push(e`INSERT INTO ${e.identifier(y)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${$}, ${p.value}, ${p.count})`);return await dt(i,c,w),ae.set(o,!0),!0},pt=async(t,n,o)=>{const r=we(n.op),a=n.field??"",_=[];for(const y of n.by??[]){const w=H(o[y]??null);_.push(w===null?e`${F(y)} IS NULL`:e`${F(y)} = ${w}`)}for(const[y,w]of Object.entries(n.where??{})){const $=w!==null&&typeof w=="object"&&!Array.isArray(w)?w.eq:w,p=H($);_.push(p===null?e`${F(y)} IS NULL`:e`${F(y)} = ${p}`)}const E=e`SELECT ${e.raw(r)}(${F(a)}) AS value FROM ${e.identifier(t)}`,f=await I(i,c,_.length>0?e`${E} WHERE ${e.join(_,e` AND `)}`:E);return oe(f[0]?.value)},Rt=async(t,n)=>{await A(i,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},Tt=async(t,n,o,r)=>{const a=J(t,n.name),{op:_}=n,E=n.field??"",f=o&&(!n.where||Oe(o,n.where))?o:void 0,y=r&&(!n.where||Oe(r,n.where))?r:void 0;if(!(!f&&!y)){if(_==="count"||_==="sum"||_==="avg"){const w=new Set;for(const[$,p]of[[f,-1],[y,1]]){if(!$)continue;const S=_==="count"?1:Fe($[E]);if(S===void 0)continue;const T=z(n.by??[],$);w.add(T),await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(C,N)=>({__count__:e`${N("__count__")} + ${C("__count__")}`,__value__:_==="count"?e`${N("__value__")} + ${C("__value__")}`:e`COALESCE(${N("__value__")}, 0) + ${C("__value__")}`}),table:a,values:[T,p*S,p]}))}for(const $ of w)await Rt(a,$);return}if(f){const w=z(n.by??[],f),$=Fe(f[E]),S=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`))[0],T=oe(S?.value),C=(S?.count??0)-1;if(C<=0)await A(i,c,e`DELETE FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`);else if(S&&$!==void 0&&T!==null&&$===T){const N=await pt(t,n,f);await A(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__value__")} = ${N}, ${e.identifier("__count__")} = ${C} WHERE ${e.identifier("__key__")} = ${w}`)}else await A(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${w}`)}if(y){const w=z(n.by??[],y),$=Fe(y[E]);if($===void 0)await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(p,S)=>({__count__:e`${S("__count__")} + 1`}),table:a,values:[w,null,1]}));else{const p=_==="min"?"MIN":"MAX";await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,T)=>({__count__:e`${T("__count__")} + 1`,__value__:e`${e.raw(p)}(COALESCE(${T("__value__")}, ${S("__value__")}), ${S("__value__")})`}),table:a,values:[w,$,1]}))}}}},Re=async t=>{const n=d.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const o of n)await pe(t,o)},ce=async(t,n,o)=>{const r=d.tables[t]?.aggregateIndexes;if(!(!r||r.length===0))for(const a of r){const _=`${t}::${a.name}`;(ae.get(_)??await Pe(t,a.name))&&await Tt(t,a,n,o)}},de=new Map,je=async(t,n)=>{const o=ne(t,n);return(await I(i,c,c.tableExists(o))).length>0},Me=async(t,n)=>{const o=`${t}::rank::${n.name}`,r=de.get(o);if(r!==void 0)return r;if(!await je(t,n.name))return de.set(o,!1),!1;const _=d.tables[t];if(!_)return de.set(o,!1),!1;const E=ne(t,n.name);await A(i,c,e`DELETE FROM ${e.identifier(E)}`);const f=n.sortBy.map((p,S)=>Q(S)),y=te(["__id__","__partition__",...f]),w=[];await ct(i,c,_,t,p=>{if(n.where&&!at(p,n.where))return;const S=Ce(n.partitionBy??[],p),T=n.sortBy.map(C=>H(p[C.field]??null));w.push([p._id,S,...T])});const $=w.map(p=>e`INSERT INTO ${e.identifier(E)} (${y}) VALUES (${re(p)})`);return await dt(i,c,$),de.set(o,!0),!0},Te=async t=>{const n=d.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const o of n)await Me(t,o)},Z=async(t,n,o,r)=>{const a=d.tables[t],_=a?.rankIndexes;if(!_||_.length===0)return;const E=a?.softDeleteMode?.field,f=E===void 0||r===void 0?void 0:r[E],y=f!=null;for(const w of _){if(o!==void 0&&r!==void 0&&gn(w,o,r))continue;const $=`${t}::rank::${w.name}`;if(!(de.get($)??await je(t,w.name)))continue;const T=ne(t,w.name);if(o&&await A(i,c,e`DELETE FROM ${e.identifier(T)} WHERE ${e.identifier("__id__")} = ${n}`),r&&!y){if(w.where&&!at(r,w.where))continue;const C=w.sortBy.map((D,K)=>Q(K)),N=te(["__id__","__partition__",...C]),B=Ce(w.partitionBy??[],r),k=w.sortBy.map(D=>H(r[D.field]??null));await A(i,c,e`INSERT INTO ${e.identifier(T)} (${N}) VALUES (${re([n,B,...k])})`)}}},le=Ct({dialect:c,exec:i,schema:d}),Ke=new Set;for(const[t,n]of Object.entries(d.tables))for(const o of Object.values(n.triggerMap??{}))Ke.add(`${t} ${o.timing} ${o.op}`);const P=(t,n,o)=>Ke.has(`${t} ${n} ${o}`);let He;const j=async(t,n,o)=>{if(ye+=1,ye>ut)throw ye-=1,new he(`trigger recursion exceeded ${String(ut)} levels on "${o.table}" — check for a self-triggering write`,"trigger");try{await tn({ctx:He,event:o,op:n,schema:d,tableName:o.table,timing:t})}finally{ye-=1}},mt=async(t,n)=>{try{await A(i,c,n)}catch(o){throw m(o)?new he(`unique constraint violation on "${t}"`,"unique"):o}},me=async(t,n)=>(await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],Se=async(t,n,o,r)=>{if(r===void 0)return;const a=e.join(Object.keys(r).map(f=>b(e`${e.identifier(f)}`,r[f])),e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${o} WHERE ${a}`:e`DELETE FROM ${e.identifier(t)} WHERE ${a}`,E=()=>{throw new he(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await I(i,c,e`${_} RETURNING ${e.identifier("id")}`)).length===0&&E();else{const f=await A(i,c,_);(c.affectedRows?c.affectedRows(f??{rowsAffected:0}):0)===0&&E()}}catch(f){throw m(f)?new he(`unique constraint violation on "${t}"`,"unique"):f}},St=(t,n,o,r)=>{const a=Object.keys(t.shape);return{columns:["id","_creationTime",...a],values:[n,o,...a.map(_=>H(r[_]??null))]}},gt=async(t,n,o,r)=>{const a=on(n,o.op,o.field,r.by,r.where);if(!a||!await pe(t,a.index))return;const E=J(t,a.index.name),f=Object.keys(a.partial);if(f.length===(a.index.by??[]).length&&f.length>0){const w=z(a.index.by??[],a.partial),$=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)} WHERE ${e.identifier("__key__")} = ${w}`);if($.length===0)return[];const p=$[0];return[{key:{...a.partial},value:qe(o.op,{count:p.count,value:oe(p.value)})}]}return f.length>0?void 0:(await I(i,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)}`)).map(w=>{const $=w;return{key:_t(JSON.parse($.key)),value:qe(o.op,{count:$.count,value:oe($.value)})}})},Ge=t=>{const n=d.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ve=t=>{throw new g("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},vt=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new g("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const o={};if(n?.relationBaseWhere)for(const r of Object.keys(d.tables)){const a=n.relationBaseWhere(r);a!==void 0&&(o[r]=a)}return{orderBy:n?.orderBy,relationPolicies:o,where:O(n?.baseWhere,n?.where),with:n?.with}},Ye=(t,n)=>Ge(t)?u?u(t,vt(t,n)):Ve(t):U.findMany(t,n),ge=(t,n,o)=>it(t,{fetcher:Ye,maxRelationKeys:h,relationBaseWhere:o,schema:d,tableName:n}),bt=$n(async(t,n)=>{const o=await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${re(n)})`),r=new Map;for(const a of o){const{id:_}=a;typeof _=="string"&&r.set(_,a)}return r}),U={async cdcChangedTables(t,n){if(x)try{return await W(),await Gn(i,t,c,{...n,retained:V!==void 0})}catch{return}},async aggregate(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);if(await W(),we(n.op),n.op==="count")return U.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new g("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const r=_e(o.softDeleteMode,void 0),a=O(O(n.baseWhere,n.where),r),_=await ge(a,t,n.relationBaseWhere),E=_!==a;if(o.aggregateIndexes&&!n.baseWhere&&!E&&!r){const S=en(o.aggregateIndexes,n.op,n.field,n.where);if(S&&await pe(t,S.index)){const C=z(S.index.by??[],S.key),N=J(t,S.index.name),k=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(N)} WHERE ${e.identifier("__key__")} = ${C}`))[0];return qe(n.op,k===void 0?void 0:{count:k.count,value:oe(k.value)})}}const f=$e(_,R),y=e.raw(we(n.op)),w=e`SELECT ${y}(${F(n.field)}) AS value FROM ${e.identifier(t)}`,p=(await I(i,c,f?e`${w} WHERE ${f}`:w))[0]?.value;return p==null?null:Number(p)},async count(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Qt(n);if(r.restrictsCounts)throw new nt(t);const a=_e(o.softDeleteMode,void 0),_=O(O(r.baseWhere,r.where),a),E=await ge(_,t,r.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!r.baseWhere&&!f&&!a){const p=Zt(o.aggregateIndexes,r.where);if(p&&await pe(t,p.index)){const T=z(p.index.by??[],p.key),C=J(t,p.index.name),N=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(C)} WHERE ${e.identifier("__key__")} = ${T}`);return Number(N[0]?.value??0)}}const y=$e(E,R),w=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,$=await I(i,c,y?e`${w} WHERE ${y}`:w);return Number($[0]?.count??0)},async delete(t,n,o){const r=await se(t,n);if(!r)return;const a=d.tables[r];if(!a)return;const _=await me(r,t),E=ie(a,_),f=o?.hard===!0,y=!f&&a.softDeleteMode?a.softDeleteMode.field:void 0;if(!(y&&(!E||E[y]!==null&&E[y]!==void 0))){if(P(r,"before","delete")&&await j("before","delete",{id:t,op:"delete",previous:E??void 0,table:r}),await Jt({deletedId:t,deletedReference:w=>E?.[w],findHolders:async(w,$,p)=>{if(d.tables[w]?.shardMode?.kind==="shardBy")throw new g("INTERNAL",`cross-backend cascade from global '${r}' into shardBy '${w}' is not supported — would require Query Coordinator fan-out across shards`);return(await U.findMany(w,{includeDeleted:f,where:{[$]:p}})).page},onCascade:(w,$)=>U.delete($,void 0,o),onRestrict:w=>{throw new he(w,"restrict")},onSetNull:(w,$,p)=>U.patch($,{[p]:null}),schema:d,tableName:r}),await Re(r),await Te(r),y&&E){const w={...E,[y]:L()},$=e.join(Object.keys(a.shape).map(p=>e`${e.identifier(p)} = ${H(w[p]??null)}`),e`, `);await Se(r,"UPDATE",$,_),await ce(r,E,w),await Z(r,t,E,void 0),await le(r,t,w,E),await X(r,t,"update",w),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E,table:r});return}await Se(r,"DELETE",void 0,_),Ne.delete(t),await ce(r,E??void 0,void 0),await Z(r,t,E??void 0,void 0),await le(r,t,void 0),await X(r,t,"delete"),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E??void 0,table:r})}},async findFirst(t,n={}){return(await U.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const o=await U.findFirst(t,n);if(o===null)throw new zt(`findFirstOrThrow: no "${t}" document matched`);return o},async findMany(t,n={}){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Gt(n.orderBy,o.shape),a=n.cursor?Vt(r,Yt(n.cursor)):void 0,_=Ye,E=async(k,D,K,ve)=>{if(Ge(k))return l?sn(l,k,D,K,ve):Ve(k);const be=d.tables[k];if(!be)throw new g("INTERNAL",`unknown table: ${k}`);const Ie=_e(be.softDeleteMode,void 0),ee={[D]:{in:K}},q=O(O(ee,ve),Ie),ue=await ge(q,k,void 0),Xe=$e(ue,R),ze=F(D);let fe=e`SELECT ${ze} AS __fk__, COUNT(*) AS count FROM ${e.identifier(k)}`;Xe&&(fe=e`${fe} WHERE ${Xe}`),fe=e`${fe} GROUP BY ${ze}`;const It=await I(i,c,fe),Je=new Map;for(const Qe of It)Je.set(Qe.__fk__,Number(Qe.count??0));return Je};let f=O(n.baseWhere,n.where);f=O(f,_e(o.softDeleteMode,n.includeDeleted)),f=await it(f,{fetcher:_,maxRelationKeys:h,relationBaseWhere:n.relationBaseWhere,schema:d,tableName:t}),a&&(f=f?{AND:[f,a]}:a);const y=$e(f,R),w=yn(r,c);let $=e`SELECT * FROM ${e.identifier(t)}`;y&&($=e`${$} WHERE ${y}`),$=e`${$} ORDER BY ${w}`;const p=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;p!==void 0&&($=e`${$} LIMIT ${e.raw(String(p+1))}`);const S=await I(i,c,$),T=wn(o,S);if(p===void 0)return n.with&&await ot({fetcher:_,groupedCounter:E,parents:T,...rt(n),schema:d,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:st(T,n.select,n.with)};const C=T.length>p,N=C?T.slice(0,p):T,B=N.at(-1);return n.with&&await ot({fetcher:_,groupedCounter:E,parents:N,...rt(n),schema:d,tableName:t,with:n.with}),{continueCursor:C&&B?Xt(B,r):null,isDone:!C,page:st(N,n.select,n.with)}},async get(t,n){const o=await se(t,n);if(!o)return null;const r=d.tables[o];return r?ie(r,await bt.load(o,t)):null},async groupBy(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=n.agg??{op:"count"};if(we(r.op),r.op!=="count"&&!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);const a=_e(o.softDeleteMode,void 0),_=O(O(n.baseWhere,n.where),a),E=await ge(_,t,n.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!n.baseWhere&&!f&&!a){const T=await gt(t,o.aggregateIndexes,r,n);if(T!==void 0)return T}const y=$e(E,R),w=n.by.map(T=>e`${F(T)} AS ${e.identifier(T)}`);if(r.op==="count")w.push(e`COUNT(*) AS value`);else{if(!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);w.push(e`${e.raw(we(r.op))}(${F(r.field)}) AS value`)}const $=e.join(n.by.map(T=>F(T)),e`, `);let p=e`SELECT ${e.join(w,e`, `)} FROM ${e.identifier(t)}`;y&&(p=e`${p} WHERE ${y}`),p=e`${p} GROUP BY ${$}`;const S=await I(i,c,p);return Sn(n.by,S)},async insert(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);await W();const a=pn(r,n,Y);De(r,a);let _,E=!0;o?.clientId!==void 0?(Ht(o.clientId),_=o.clientId):o?.allowExplicitId&&typeof a._id=="string"?_=a._id:(_=M(),E=!1);const f=o?.allowExplicitId&&typeof a._creationTime=="number"?a._creationTime:L(),y={...a,_creationTime:f,_id:_};P(t,"before","insert")&&await j("before","insert",{doc:{...y},id:_,op:"insert",table:t}),await Re(t),await Te(t);const{columns:w,values:$}=St(r,_,f,a);return await mt(t,e`INSERT INTO ${e.identifier(t)} (${te(w)}) VALUES (${re($)})`),E&&Ne.set(_,t),await ce(t,void 0,y),await Z(t,_,void 0,y),await le(t,_,y),await X(t,_,"insert",y),P(t,"after","insert")&&await j("after","insert",{doc:y,id:_,op:"insert",table:t}),_},normalizeId(t,n){return Kt(d,t,n)},async patch(t,n,o){Ze("patch",n);const r=await se(t,o);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const a=d.tables[r];if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=await me(r,t),E=ie(a,_);if(!E)throw new g("INTERNAL",`document not found: ${t}`);const f={...E,...n,_id:t};ft(a,n,f,Y),De(a,f,!0),P(r,"before","update")&&await j("before","update",{doc:{...f},id:t,op:"update",previous:E,table:r}),await Re(r),await Te(r);const y=Object.keys(a.shape),w=e.join(y.map($=>e`${e.identifier($)} = ${H(f[$]??null)}`),e`, `);await Se(r,"UPDATE",w,_),await ce(r,E,f),await Z(r,t,E,f),await le(r,t,f,E),await X(r,t,"update",f),P(r,"after","update")&&await j("after","update",{doc:f,id:t,op:"update",previous:E,table:r})},async restore(t,n){const o=await se(t,n);if(!o)throw new g("INTERNAL",`document not found: ${t}`);const r=d.tables[o],a=r?.softDeleteMode?.field;if(!r||!a)throw new g("INTERNAL",`ctx.db.restore: table "${o}" is not a .softDelete() table`);const _=await me(o,t),E=_?.[a]!==null&&_?.[a]!==void 0;if(await U.patch(t,{[a]:null},n),E){const f=ie(r,_);f!==null&&await Z(o,t,void 0,{...f,[a]:null})}},query(t){const n=d.tables[t];if(!n)throw new g("INTERNAL",`unknown table: ${t}`);const o="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",r=[],a=f=>r.every(y=>y(f)),_=async(f,y)=>{await W();const w=r.length>0,$=await Dt(i,c,n,t,f,qt(w?void 0:y));if(!w)return y===void 0&&Ot($),$;const p=$.filter(S=>a(S));return y===void 0?p:p.slice(0,y)},E=f=>{const y={async*[Symbol.asyncIterator](){if(!f)throw new g("INTERNAL",o);yield*await _(f,void 0)},async collect(){if(!f)throw new g("INTERNAL",o);return _(f,void 0)},async collectWithScores(){throw new g("GLOBAL_SEARCH_SCORES_UNSUPPORTED",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(w){return r.push(w),y},async first(){if(!f)throw new g("INTERNAL",o);return(await _(f,1))[0]??null},order(){return y},async paginate(w){if(!f)throw new g("INTERNAL",o);const $=kt(w);return Mt(await _(f,Ft($)),$)},async take(w){if(!f)throw new g("INTERNAL",o);return _(f,w)},async unique(){if(!f)throw new g("INTERNAL",o);const w=await _(f,2);if(w.length>1)throw new dn(`unique() on table "${t}" matched ${String(w.length)} documents; expected at most one`);return w[0]??null},withGeoIndex(){throw new g("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new g("INTERNAL",o)},withSearchIndex(w,$){const p=(n.searchIndexes??[]).find(T=>T.name===w);if(!p)throw new g("INTERNAL",`unknown search index "${w}" on table "${t}"`);const S={definition:p,field:p.field,filters:[],hasQuery:!1,indexName:w,query:""};if($(Lt(S,t,Nt(p.language))),!S.hasQuery)throw new g("INTERNAL",`search index "${w}" on table "${t}" requires a .search(field, query) call`);return E(S)}};return y};return E(void 0)},async rank(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(D=>D.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(o.restrictsCounts)throw new nt(t);if(await W(),!await Me(t,a))return null;const E=typeof o.row=="string"?o.row:o.row._id;if(!E)return null;const f=ne(t,a.name),y=a.sortBy.map((D,K)=>Q(K)),w=te(["__partition__",...y]),p=(await I(i,c,e`SELECT ${w} FROM ${e.identifier(f)} WHERE ${e.identifier("__id__")} = ${E}`))[0];if(!p)return null;const S=p.__partition__,T=O(o.baseWhere,o.where);et(T,d,t,"rank");const C=tt(a,T);if(C&&Ce(a.partitionBy??[],C)!==S)return null;const N=vn(c.name,a,y,p,E),B=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}${N?e` AND (${N})`:e``}`),k=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(B[0]?.c??0)+1,total:Number(k[0]?.c??0)}},async rankPage(t,n,o={}){et(O(o.baseWhere,o.where),d,t,"rankPage");const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(q=>q.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await W(),!await Me(t,a))return{continueCursor:null,isDone:!0,page:[]};const E=ne(t,a.name),f=a.sortBy.map((q,ue)=>Q(ue)),y=Math.max(1,Math.min(1e3,Math.floor(o.take??100))),w=O(o.baseWhere,o.where),$=tt(a,w),p=In(a,f),S=e.join(p.map(q=>e`${e.identifier(q.column)} ${e.raw(q.direction==="desc"?"DESC":"ASC")}`),e`, `),T=[];typeof o.partitionKey=="string"?T.push(e`${e.identifier("__partition__")} = ${o.partitionKey}`):$&&T.push(e`${e.identifier("__partition__")} = ${Ce(a.partitionBy??[],$)}`);const C=jt(o);if(C!==void 0){const q=bn(c.name,p,C);q!==void 0&&T.push(q)}const N=te([Ee,"__partition__",...f]);let B=e`SELECT ${N} FROM ${e.identifier(E)}`;T.length>0&&(B=e`${B} WHERE ${e.join(T,e` AND `)}`),B=e`${B} ORDER BY ${S} LIMIT ${e.raw(String(y+1))}`;const k=await I(i,c,B),D=k.length>y,K=D?k.slice(0,y):k,ve=K.map(q=>q[Ee]),be=await Cn(i,c,r,t,ve);let Ie=null;const ee=K.at(-1);if(D&&ee!==void 0){const q=[ee.__partition__,...f.map(ue=>ee[ue]),ee[Ee]];Ie=An(q)}return{continueCursor:Ie,isDone:!D,page:be}},async replace(t,n,o,r){Ze("replace",n);const a=await se(t,o);if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=d.tables[a];if(!_)throw new g("INTERNAL",`document not found: ${t}`);const E=await me(a,t);if(E===void 0)throw new g("INTERNAL",`document not found: ${t}`);const y=Pt(d,a,"update")||(_.aggregateIndexes??[]).length>0||(_.rankIndexes??[]).length>0?ie(_,E)??void 0:void 0,w=r?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:L(),$={...n,_creationTime:w,_id:t};ft(_,n,$,Y),De(_,$),P(a,"before","update")&&await j("before","update",{doc:{...$},id:t,op:"update",previous:y,table:a}),await Re(a),await Te(a);const p=Object.keys(_.shape),S=e.join([e`${e.identifier("_creationTime")} = ${w}`,...p.map(T=>e`${e.identifier(T)} = ${H($[T]??null)}`)],e`, `);await Se(a,"UPDATE",S,E),await ce(a,y,$),await Z(a,t,y,$),await le(a,t,$,y),await X(a,t,"update",$),P(a,"after","update")&&await j("after","update",{doc:$,id:t,op:"update",previous:y,table:a})}};return He={db:U,scheduler:yt},U};export{oi as backfillSqlSearchIndexes,ti as createSqlCtxDb,si as decodeGlobalRow,Gn as readSqlCdcChangedTables,ei as readSqlCdcChanges,Et as readSqlCdcFloor,Dn as runSqlAggregateMigrations,Un as runSqlCdcMigration,Mn as runSqlGlobalTableMigrations,Fn as runSqlRankMigrations,At as runSqlSearchMigrations,jn as sweepSqlCdcRetention};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/sql-store",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.103",
|
|
4
4
|
"description": "Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@lunora/errors": "1.0.0-alpha.27",
|
|
54
|
-
"@lunora/shard-engine": "1.0.0-alpha.
|
|
54
|
+
"@lunora/shard-engine": "1.0.0-alpha.50",
|
|
55
55
|
"drizzle-orm": "^0.45.2"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{LunoraError as g}from"@lunora/errors";import{c as It,r as At,A as Lt,q as kt,C as Nt,R as Mt,a as Dt,T as qt,x as Ot,b as Ft}from"./ctx-db-search-BiMTuJzw.mjs";import{d as ii}from"./ctx-db-search-BiMTuJzw.mjs";import{literalInList as Bt,throwingScheduler as xt,CDC_LOG_TABLE as G,cursorBelowRetainedFloor as Wt,cdcTrimmedError as Ut,aggregateTableName as J,rankTableName as ne,assertNoExplicitUndefined as Ze,hasTrigger as Pt,runRowValidators as De,assertFlatPredicate as et,mergeWhere as O,sortColumnName as Q,resolveRankPartition as tt,encodePartitionKey as Ie,resolveRankSeekTuple as jt,RANK_TIEBREAK as Ee,CountRlsUnsupportedError as nt,normalizeIdStructurally as Kt,assertValidClientId as Ht,aggregateSqlFunction as we,softDeleteScope as _e,compileWhereSql as $e,normalizeOrderKeys as Gt,buildSeekWhere as Vt,decodeCursor as Yt,resolveRelationPredicates as it,resolveWith as ot,relationHooks as rt,applySelect as st,encodeCursor as Xt,NotFoundError as zt,applyOnDelete as Jt,ConflictError as he,normalizeCountArgument as Qt,selectIndexForCount as Zt,encodeAggregateKey as z,selectIndexForAggregate as en,readAggregateValue as qe,runTriggers as tn,matchesRankStaticWhere as at,CURSOR_PREFIX as nn,selectIndexForGroupBy as on,tiebreakDirectionFor as rn,fanOutScalarCounts as sn,matchesStaticWhere as Oe,foldAggregateTally as an,coerceAggregateNumber as Fe,CDC_LOG_TABLE_SEQ_INDEX as cn,NotUniqueError as dn}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{d as _t,e as Le,n as ln,b as un}from"./value-codec-CwTLrqfU.mjs";import{migrateSearchState as fn}from"./SEARCH_STATE_TABLE-B5a5xBwB.mjs";import{queryAll as C,queryRun as A,createIndexIfNotExists as Ae,decodeRow as ie,serializeColumnValue as H,columnRefSql as F,decodeRows as wn,forEachRowPaged as ct,queryBatch as dt}from"./decodeGlobalRow-C8O2hy0d.mjs";import{decodeGlobalRow as ri}from"./decodeGlobalRow-C8O2hy0d.mjs";const _n=(s,u)=>{if(s.size<u)return;const l=s.keys().next().value;l!==void 0&&s.delete(l)},lt=50,$n=(s,u={})=>{const l=u.maxBatch??lt,i=Number.isInteger(l)&&l>0?l:lt,h=new Map;let d=!1;const c=async(R,b)=>{const v=[...b.keys()];for(let L=0;L<v.length;L+=i){const M=v.slice(L,L+i);try{const x=await s(R,M);for(const V of M){const Y=x.get(V);for(const X of b.get(V)??[])X.resolve(Y)}}catch(x){for(const V of M)for(const Y of b.get(V)??[])Y.reject(x)}}},m=()=>{d=!1;const R=[...h.entries()];h.clear();for(const[b,v]of R)c(b,v).catch(()=>{})};return{async load(R,b){return new Promise((v,L)=>{let M=h.get(R);M||(M=new Map,h.set(R,M));const x=M.get(b);x?x.push({reject:L,resolve:v}):M.set(b,[{reject:L,resolve:v}]),d||(d=!0,queueMicrotask(m))})}}},hn=new Set(["_id","id"]),We=(s,u,l)=>s==="postgres"?e`${u} IS NOT DISTINCT FROM ${l}`:s==="mysql"?e`${u} <=> ${l}`:e`${u} IS ${l}`,En=s=>{const u=s.map(l=>e`${F(l.field)} ${e.raw(l.direction==="desc"?"DESC":"ASC")}`);if(!s.some(l=>hn.has(l.field))){const l=rn(s);u.push(e`${F("id")} ${e.raw(l==="desc"?"DESC":"ASC")}`)}return e.join(u,e`, `)},ut=50,Ue=s=>{const u=[];for(const[l,i]of Object.entries(s.shape)){const h=i._meta?.column;h&&u.push([l,h])}return u},yn=(s,u,l)=>{const i={...u};for(const[h,d]of Ue(s)){if(d.serverDefault){i[h]=d.serverDefault({auth:l});continue}i[h]===void 0&&(d.defaultFn?i[h]=d.defaultFn():"defaultValue"in d&&(i[h]=d.defaultValue))}return i},ft=(s,u,l,i)=>{for(const[h,d]of Ue(s)){if(d.serverDefault){h in u&&(l[h]=d.serverDefault({auth:i}));continue}d.onUpdateFn&&!(h in u)&&(l[h]=d.onUpdateFn())}},pn=128,Rn=()=>{const s=new Map;return{delete:u=>{s.delete(u)},get:u=>{const l=s.get(u);if(l!==void 0)return s.delete(u),s.set(u,l),l},set:(u,l)=>{s.has(u)?s.delete(u):_n(s,pn),s.set(u,l)}}},Tn=async(s,u,l,i,h)=>{const d=h.get(i);if(d!==void 0)return d;const c=Object.entries(l.tables).filter(([,R])=>R.shardMode===void 0||R.shardMode.kind==="global").map(([R])=>R),m=await Promise.all(c.map(async R=>({found:(await C(s,u,e`SELECT 1 FROM ${e.identifier(R)} WHERE ${e.identifier("id")} = ${i} LIMIT 1`)).length>0,tableName:R})));for(const R of m)if(R.found)return h.set(i,R.tableName),R.tableName},oe=s=>s==null?null:Number(s),mn=(s,u)=>u.map(l=>{const i={};for(const h of s)i[h]=l[h]??null;return{key:i,value:oe(l.value)}}),Sn=(s,u,l)=>[...s.partitionBy??[],...s.sortBy.map(h=>h.field),...s.where?Object.keys(s.where):[]].every(h=>u[h]===l[h]),$t=s=>s.length===1?s[0]:e`(${e.join(s,e` AND `)})`,te=s=>e.join(s.map(u=>e`${e.identifier(u)}`),e`, `),re=s=>e.join(s.map(u=>e`${u}`),e`, `),gn=(s,u,l,i,h)=>{const d=[];for(let c=0;c<l.length+1;c+=1){const m=l.slice(0,c).map(v=>We(s,e`${e.identifier(v)}`,i[v])),R=l[c],b=u.sortBy[c];c<l.length&&R!==void 0&&b!==void 0?m.push(e`${e.identifier(R)} ${e.raw(b.direction==="desc"?">":"<")} ${i[R]}`):m.push(e`${e.identifier(Ee)} < ${h}`),d.push($t(m))}return d.length>0?e.join(d,e` OR `):void 0},vn=(s,u,l)=>{if(l.length!==u.length)return;const i=[];for(const[h,d]of u.entries()){const c=[];for(let m=0;m<h;m+=1){const R=u[m];R!==void 0&&c.push(We(s,e`${e.identifier(R.column)}`,l[m]))}c.push(e`${e.identifier(d.column)} ${e.raw(d.direction==="desc"?"<":">")} ${l[h]}`),i.push($t(c))}return e`(${e.join(i,e` OR `)})`},bn=(s,u)=>{if(s.sortBy.length===0)throw new g("INTERNAL",`rankIndex "${s.name}" requires at least one "sortBy" column for stable pagination`);const l=[{column:"__partition__",direction:"asc"}];for(const[i,h]of s.sortBy.entries())l.push({column:u[i]??Q(i),direction:h.direction});return l.push({column:Ee,direction:"asc"}),l},Cn=async(s,u,l,i,h)=>{const c=[];for(let v=0;v<h.length;v+=50)c.push(h.slice(v,v+50));const m=await Promise.all(c.map(async v=>C(s,u,e`SELECT * FROM ${e.identifier(i)} WHERE ${e.identifier("id")} IN (${re(v)})`))),R=new Map;for(const v of m)for(const L of v)R.set(L.id,L);const b=[];for(const v of h){const L=ie(l,R.get(v));L&&b.push(L)}return b},In=s=>{const u=JSON.stringify(s),l=new TextEncoder().encode(u);let i="";for(const h of l)i+=String.fromCodePoint(h);return nn+btoa(i)},An=(s,u)=>u.columnType(Le(s)),Ln=(s,u,l)=>{const i=[];for(const[c,m]of Object.entries(u.shape)){if(!m._meta?.column)continue;const R=m._meta.column.notNull&&m.kind!=="optional"?" NOT NULL":"";i.push(e`${e.identifier(c)} ${e.raw(`${An(m,l)}${R}`)}`)}const h=l.frameworkColumns().map(c=>e`${e.identifier(c.name)} ${e.raw(c.type)}`),d=h.length+i.length;if(l.maxTableColumns!==void 0&&d>l.maxTableColumns)throw new g("VALIDATION_ERROR",`@lunora/sql-store: global table "${s}" needs ${String(d)} columns, over this engine's ${String(l.maxTableColumns)}-column limit — split the table, or move the extra fields into one object field`);return e.join([...h,...i],e`, `)},kn=async(s,u,l,i)=>{const h=d=>{const c=F(d),m=l.shape[d],R=m&&i.indexKeyPrefix?i.indexKeyPrefix(Le(m)):void 0;return R===void 0?c:e`${c}(${e.raw(String(R))})`};for(const d of l.indexes){const c=e.join(d.fields.map(m=>h(m)),e`, `);await Ae(s,i,{columns:c,name:`${u}_${d.name}`,table:u,unique:d.unique??!1})}for(const[d,c]of Ue(l))c.unique&&await Ae(s,i,{columns:h(d),name:`${u}_unique_${d}`,table:u,unique:!0})},Nn=async(s,u,l)=>{for(const[i,h]of Object.entries(u.tables)){if(h.shardMode?.kind!=="global")continue;const d=Ln(i,h,l);await A(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(i)} (${d})`),await kn(s,i,h,l)}},Mn=async(s,u,l)=>{const{integer:i,key:h,real:d}=l.companionTypes;for(const[c,m]of Object.entries(u.tables)){const R=m.aggregateIndexes;if(!(!R||R.length===0))for(const b of R){const v=J(c,b.name);await A(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(v)} (${e.identifier("__key__")} ${e.raw(h)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(d)}, ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0)`),l.name==="sqlite"&&((await C(s,l,e`PRAGMA table_info(${e.identifier(v)})`)).some(M=>M.name==="__count__")||await A(s,l,e`ALTER TABLE ${e.identifier(v)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0`))}}},Be=(s,u,l,i)=>{const h=s.name==="mysql"&&i?e`${e.identifier(u)}(191)`:e`${e.identifier(u)}`;return e`${h} ${e.raw(l)}`},Dn=(s,u,l)=>{const i=[Be(s,"__partition__","ASC",!0)];for(const[h,d]of u.sortBy.entries()){const c=l.shape[d.field],m=c!==void 0&&s.indexKeyPrefix?.(Le(c))!==void 0;i.push(Be(s,Q(h),d.direction==="desc"?"DESC":"ASC",m))}return i.push(Be(s,"__id__","ASC",!0)),i},qn=(s,u,l)=>u.sortBy.map((i,h)=>{const d=l.shape[i.field],c=s.columnType(d?Le(d):void 0);return e`${e.identifier(Q(h))} ${e.raw(c)}`}),On=async(s,u,l)=>{const{key:i}=l.companionTypes;for(const[h,d]of Object.entries(u.tables)){const c=d.rankIndexes;if(!(!c||c.length===0))for(const m of c){const R=ne(h,m.name),b=qn(l,m,d),v=b.length>0?e`, ${e.join(b,e`, `)}`:e``;await A(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(R)} (${e.identifier("__id__")} ${e.raw(i)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(i)} NOT NULL${v})`);const L=Dn(l,m,d),M=`${h}__rank_${m.name}__btree`;await Ae(s,l,{columns:e.join(L,e`, `),name:M,table:R,unique:!1})}}},xe="__cdc_sweep",ht="global",Fn=6e4,Bn=1e4,xn=3e4;let wt=0;const Wn=async(s,u)=>{const{autoincrementPrimaryKey:l,key:i,real:h,text:d}=u.companionTypes;await A(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(G)} (${e.identifier("seq")} ${e.raw(l)}, ${e.identifier("ts")} ${e.raw(h)} NOT NULL, ${e.identifier("table")} ${e.raw(i)} NOT NULL, ${e.identifier("id")} ${e.raw(i)} NOT NULL, ${e.identifier("op")} ${e.raw(i)} NOT NULL, ${e.identifier("doc")} ${e.raw(d)})`);const c=u.indexKeyPrefix?.("string");await Ae(s,u,{columns:e`${c===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(c))})`}, ${e.identifier("seq")}`,name:cn,table:G,unique:!1}),await A(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(xe)} (${e.identifier("id")} ${e.raw(i)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(h)} NOT NULL)`),await A(s,u,e`INSERT INTO ${e.identifier(xe)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${ht}, ${0}) ${u.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},Un=async(s,u,l)=>{const i=e`UPDATE ${e.identifier(xe)} SET ${e.identifier("lease_until")} = ${l+Fn} WHERE ${e.identifier("id")} = ${ht} AND ${e.identifier("lease_until")} <= ${l}`;if(u.supportsReturning)return(await C(s,u,e`${i} RETURNING ${e.identifier("id")}`)).length>0;const h=await A(s,u,i);return(u.affectedRows?u.affectedRows(h??{rowsAffected:0}):0)>0},Pn=async(s,u,l,i)=>{if(!await Un(s,u,i))return;const h=i-l;await A(s,u,e`
|
|
2
|
-
DELETE FROM ${e.identifier(G)} WHERE ${e.identifier("seq")} IN (
|
|
3
|
-
SELECT ${e.identifier("seq")} FROM (
|
|
4
|
-
SELECT ${e.identifier("seq")} FROM ${e.identifier(G)} WHERE ${e.identifier("ts")} <= ${h} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Bn))}
|
|
5
|
-
) AS ${e.identifier("expired")}
|
|
6
|
-
)
|
|
7
|
-
`)},Et=async(s,u)=>{const l=await C(s,u,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(G)}`),i=Number(l[0]?.seq??Number.NaN);return Number.isFinite(i)?i:void 0},jn=s=>JSON.stringify(ln(s)?un(s):s),Kn=async(s,u,l,i,h,d,c)=>{await A(s,c,e`INSERT INTO ${e.identifier(G)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${u}, ${l}, ${i}, ${h}, ${d===void 0?null:jn(d)})`)},Zn=async(s,u,l)=>{const i=u.sinceSeq??0,h=Math.max(1,Math.min(u.limit??1e3,1e4)),d=await Et(s,l);if(d!==void 0&&Wt(d,i))throw Ut(d,i,"global");const m=(await C(s,l,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(G)} WHERE seq > ${i} ORDER BY seq ASC LIMIT ${e.raw(String(h))}`)).map(R=>{const{doc:b}=R,v={id:String(R.id),op:String(R.op),seq:Number(R.seq),table:String(R.table),ts:Number(R.ts)};return typeof b=="string"?{...v,doc:_t(JSON.parse(b))}:v});return{changes:m,cursor:m.at(-1)?.seq??i}},Hn=async(s,u,l,i={})=>{if(i.cursorOnly){const R=await C(s,l,e`SELECT MAX(seq) AS seq FROM ${e.identifier(G)}`),b=Number(R[0]?.seq??u);return{cursor:Number.isFinite(b)?b:u,tables:[]}}const h=await C(s,l,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(G)} WHERE seq > ${u} GROUP BY ${e.identifier("table")}`);let d=u;const c=[];for(const R of h){const b=Number(R.seq);Number.isFinite(b)&&b>d&&(d=b),c.push(String(R.table))}const m=i.retained===!0?await Et(s,l):void 0;return{cursor:d,tables:c,...m===void 0?{}:{floor:m}}},ei=s=>{const{crossShardCounter:u,crossShardReader:l,exec:i,maxRelationKeys:h,schema:d}=s,{dialect:c}=s,{isUniqueViolation:m}=c,R={fieldRef:F,serialize:H,...c.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...c.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...c.name==="sqlite"?{}:{inList:Bt}},b=(t,n)=>We(c.name,t,n),v=t=>{const n=te(t.columns),o=re(t.values),r=f=>c.name==="mysql"?e`VALUES(${e.identifier(f)})`:e`excluded.${e.identifier(f)}`,a=f=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(f)}`:e`${e.identifier(f)}`,_=e.join(Object.entries(t.set(r,a)).map(([f,y])=>e`${e.identifier(f)} = ${y}`),e`, `),E=c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${_}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${_}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${o}) ${E}`},L=s.clock??(()=>Date.now()),M=s.idGenerator??(()=>crypto.randomUUID()),x=s.cdc??!1,V=typeof s.cdcRetentionMs=="number"&&Number.isFinite(s.cdcRetentionMs)&&s.cdcRetentionMs>0?s.cdcRetentionMs:void 0,Y=s.auth??{identity:null,userId:null},X=async(t,n,o,r)=>{if(!x||(await Kn(i,L(),t,n,o,r,c),V===void 0))return;const a=L();if(!(a-wt<xn)){wt=a;try{await Pn(i,c,V,a)}catch{}}},yt=s.scheduler??xt,ke=Rn();let ye=0,Ne;const W=async()=>(Ne??=(async()=>{await Nn(i,d,c),await Mn(i,d,c),await On(i,d,c),await fn(i,c),await At(i,d,c),x&&await Wn(i,c)})().catch(t=>{throw Ne=void 0,t}),Ne),se=async(t,n)=>{await W();const o=await Tn(i,c,d,t,ke);if(!(n!==void 0&&o!==n))return o},ae=new Map,Pe=async(t,n)=>{const o=J(t,n);return(await C(i,c,c.tableExists(o))).length>0},pe=async(t,n)=>{const o=`${t}::${n.name}`,r=ae.get(o);if(r!==void 0)return r;if(!await Pe(t,n.name))return ae.set(o,!1),!1;const _=d.tables[t];if(!_)return ae.set(o,!1),!1;const E=n.by??[],f=new Map;await ct(i,c,_,t,$=>{if(n.where&&!Oe($,n.where))return;const p=z(E,$);an(f,p,n,$)});const y=J(t,n.name);await A(i,c,e`DELETE FROM ${e.identifier(y)}`);const w=[];for(const[$,p]of f)w.push(e`INSERT INTO ${e.identifier(y)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${$}, ${p.value}, ${p.count})`);return await dt(i,c,w),ae.set(o,!0),!0},pt=async(t,n,o)=>{const r=we(n.op),a=n.field??"",_=[];for(const y of n.by??[]){const w=H(o[y]??null);_.push(w===null?e`${F(y)} IS NULL`:e`${F(y)} = ${w}`)}for(const[y,w]of Object.entries(n.where??{})){const $=w!==null&&typeof w=="object"&&!Array.isArray(w)?w.eq:w,p=H($);_.push(p===null?e`${F(y)} IS NULL`:e`${F(y)} = ${p}`)}const E=e`SELECT ${e.raw(r)}(${F(a)}) AS value FROM ${e.identifier(t)}`,f=await C(i,c,_.length>0?e`${E} WHERE ${e.join(_,e` AND `)}`:E);return oe(f[0]?.value)},Rt=async(t,n)=>{await A(i,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},Tt=async(t,n,o,r)=>{const a=J(t,n.name),{op:_}=n,E=n.field??"",f=o&&(!n.where||Oe(o,n.where))?o:void 0,y=r&&(!n.where||Oe(r,n.where))?r:void 0;if(!(!f&&!y)){if(_==="count"||_==="sum"||_==="avg"){const w=new Set;for(const[$,p]of[[f,-1],[y,1]]){if(!$)continue;const S=_==="count"?1:Fe($[E]);if(S===void 0)continue;const T=z(n.by??[],$);w.add(T),await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(I,k)=>({__count__:e`${k("__count__")} + ${I("__count__")}`,__value__:_==="count"?e`${k("__value__")} + ${I("__value__")}`:e`COALESCE(${k("__value__")}, 0) + ${I("__value__")}`}),table:a,values:[T,p*S,p]}))}for(const $ of w)await Rt(a,$);return}if(f){const w=z(n.by??[],f),$=Fe(f[E]),S=(await C(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`))[0],T=oe(S?.value),I=(S?.count??0)-1;if(I<=0)await A(i,c,e`DELETE FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`);else if(S&&$!==void 0&&T!==null&&$===T){const k=await pt(t,n,f);await A(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__value__")} = ${k}, ${e.identifier("__count__")} = ${I} WHERE ${e.identifier("__key__")} = ${w}`)}else await A(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${w}`)}if(y){const w=z(n.by??[],y),$=Fe(y[E]);if($===void 0)await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(p,S)=>({__count__:e`${S("__count__")} + 1`}),table:a,values:[w,null,1]}));else{const p=_==="min"?"MIN":"MAX";await A(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,T)=>({__count__:e`${T("__count__")} + 1`,__value__:e`${e.raw(p)}(COALESCE(${T("__value__")}, ${S("__value__")}), ${S("__value__")})`}),table:a,values:[w,$,1]}))}}}},Re=async t=>{const n=d.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const o of n)await pe(t,o)},ce=async(t,n,o)=>{const r=d.tables[t]?.aggregateIndexes;if(!(!r||r.length===0))for(const a of r){const _=`${t}::${a.name}`;(ae.get(_)??await Pe(t,a.name))&&await Tt(t,a,n,o)}},de=new Map,je=async(t,n)=>{const o=ne(t,n);return(await C(i,c,c.tableExists(o))).length>0},Me=async(t,n)=>{const o=`${t}::rank::${n.name}`,r=de.get(o);if(r!==void 0)return r;if(!await je(t,n.name))return de.set(o,!1),!1;const _=d.tables[t];if(!_)return de.set(o,!1),!1;const E=ne(t,n.name);await A(i,c,e`DELETE FROM ${e.identifier(E)}`);const f=n.sortBy.map((p,S)=>Q(S)),y=te(["__id__","__partition__",...f]),w=[];await ct(i,c,_,t,p=>{if(n.where&&!at(p,n.where))return;const S=Ie(n.partitionBy??[],p),T=n.sortBy.map(I=>H(p[I.field]??null));w.push([p._id,S,...T])});const $=w.map(p=>e`INSERT INTO ${e.identifier(E)} (${y}) VALUES (${re(p)})`);return await dt(i,c,$),de.set(o,!0),!0},Te=async t=>{const n=d.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const o of n)await Me(t,o)},Z=async(t,n,o,r)=>{const a=d.tables[t],_=a?.rankIndexes;if(!_||_.length===0)return;const E=a?.softDeleteMode?.field,f=E===void 0||r===void 0?void 0:r[E],y=f!=null;for(const w of _){if(o!==void 0&&r!==void 0&&Sn(w,o,r))continue;const $=`${t}::rank::${w.name}`;if(!(de.get($)??await je(t,w.name)))continue;const T=ne(t,w.name);if(o&&await A(i,c,e`DELETE FROM ${e.identifier(T)} WHERE ${e.identifier("__id__")} = ${n}`),r&&!y){if(w.where&&!at(r,w.where))continue;const I=w.sortBy.map((D,K)=>Q(K)),k=te(["__id__","__partition__",...I]),B=Ie(w.partitionBy??[],r),N=w.sortBy.map(D=>H(r[D.field]??null));await A(i,c,e`INSERT INTO ${e.identifier(T)} (${k}) VALUES (${re([n,B,...N])})`)}}},le=It({dialect:c,exec:i,schema:d}),Ke=new Set;for(const[t,n]of Object.entries(d.tables))for(const o of Object.values(n.triggerMap??{}))Ke.add(`${t} ${o.timing} ${o.op}`);const P=(t,n,o)=>Ke.has(`${t} ${n} ${o}`);let He;const j=async(t,n,o)=>{if(ye+=1,ye>ut)throw ye-=1,new he(`trigger recursion exceeded ${String(ut)} levels on "${o.table}" — check for a self-triggering write`,"trigger");try{await tn({ctx:He,event:o,op:n,schema:d,tableName:o.table,timing:t})}finally{ye-=1}},mt=async(t,n)=>{try{await A(i,c,n)}catch(o){throw m(o)?new he(`unique constraint violation on "${t}"`,"unique"):o}},me=async(t,n)=>(await C(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],Se=async(t,n,o,r)=>{if(r===void 0)return;const a=e.join(Object.keys(r).map(f=>b(e`${e.identifier(f)}`,r[f])),e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${o} WHERE ${a}`:e`DELETE FROM ${e.identifier(t)} WHERE ${a}`,E=()=>{throw new he(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await C(i,c,e`${_} RETURNING ${e.identifier("id")}`)).length===0&&E();else{const f=await A(i,c,_);(c.affectedRows?c.affectedRows(f??{rowsAffected:0}):0)===0&&E()}}catch(f){throw m(f)?new he(`unique constraint violation on "${t}"`,"unique"):f}},St=(t,n,o,r)=>{const a=Object.keys(t.shape);return{columns:["id","_creationTime",...a],values:[n,o,...a.map(_=>H(r[_]??null))]}},gt=async(t,n,o,r)=>{const a=on(n,o.op,o.field,r.by,r.where);if(!a||!await pe(t,a.index))return;const E=J(t,a.index.name),f=Object.keys(a.partial);if(f.length===(a.index.by??[]).length&&f.length>0){const w=z(a.index.by??[],a.partial),$=await C(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)} WHERE ${e.identifier("__key__")} = ${w}`);if($.length===0)return[];const p=$[0];return[{key:{...a.partial},value:qe(o.op,{count:p.count,value:oe(p.value)})}]}return f.length>0?void 0:(await C(i,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)}`)).map(w=>{const $=w;return{key:_t(JSON.parse($.key)),value:qe(o.op,{count:$.count,value:oe($.value)})}})},Ge=t=>{const n=d.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ve=t=>{throw new g("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},vt=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new g("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const o={};if(n?.relationBaseWhere)for(const r of Object.keys(d.tables)){const a=n.relationBaseWhere(r);a!==void 0&&(o[r]=a)}return{orderBy:n?.orderBy,relationPolicies:o,where:O(n?.baseWhere,n?.where),with:n?.with}},Ye=(t,n)=>Ge(t)?l?l(t,vt(t,n)):Ve(t):U.findMany(t,n),ge=(t,n,o)=>it(t,{fetcher:Ye,maxRelationKeys:h,relationBaseWhere:o,schema:d,tableName:n}),bt=$n(async(t,n)=>{const o=await C(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${re(n)})`),r=new Map;for(const a of o){const{id:_}=a;typeof _=="string"&&r.set(_,a)}return r}),U={async cdcChangedTables(t,n){if(x)try{return await W(),await Hn(i,t,c,{...n,retained:V!==void 0})}catch{return}},async aggregate(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);if(await W(),we(n.op),n.op==="count")return U.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new g("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const r=_e(o.softDeleteMode,void 0),a=O(O(n.baseWhere,n.where),r),_=await ge(a,t,n.relationBaseWhere),E=_!==a;if(o.aggregateIndexes&&!n.baseWhere&&!E&&!r){const S=en(o.aggregateIndexes,n.op,n.field,n.where);if(S&&await pe(t,S.index)){const I=z(S.index.by??[],S.key),k=J(t,S.index.name),N=(await C(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(k)} WHERE ${e.identifier("__key__")} = ${I}`))[0];return qe(n.op,N===void 0?void 0:{count:N.count,value:oe(N.value)})}}const f=$e(_,R),y=e.raw(we(n.op)),w=e`SELECT ${y}(${F(n.field)}) AS value FROM ${e.identifier(t)}`,p=(await C(i,c,f?e`${w} WHERE ${f}`:w))[0]?.value;return p==null?null:Number(p)},async count(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Qt(n);if(r.restrictsCounts)throw new nt(t);const a=_e(o.softDeleteMode,void 0),_=O(O(r.baseWhere,r.where),a),E=await ge(_,t,r.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!r.baseWhere&&!f&&!a){const p=Zt(o.aggregateIndexes,r.where);if(p&&await pe(t,p.index)){const T=z(p.index.by??[],p.key),I=J(t,p.index.name),k=await C(i,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(I)} WHERE ${e.identifier("__key__")} = ${T}`);return Number(k[0]?.value??0)}}const y=$e(E,R),w=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,$=await C(i,c,y?e`${w} WHERE ${y}`:w);return Number($[0]?.count??0)},async delete(t,n,o){const r=await se(t,n);if(!r)return;const a=d.tables[r];if(!a)return;const _=await me(r,t),E=ie(a,_),f=o?.hard===!0,y=!f&&a.softDeleteMode?a.softDeleteMode.field:void 0;if(!(y&&(!E||E[y]!==null&&E[y]!==void 0))){if(P(r,"before","delete")&&await j("before","delete",{id:t,op:"delete",previous:E??void 0,table:r}),await Jt({deletedId:t,deletedReference:w=>E?.[w],findHolders:async(w,$,p)=>{if(d.tables[w]?.shardMode?.kind==="shardBy")throw new g("INTERNAL",`cross-backend cascade from global '${r}' into shardBy '${w}' is not supported — would require Query Coordinator fan-out across shards`);return(await U.findMany(w,{includeDeleted:f,where:{[$]:p}})).page},onCascade:(w,$)=>U.delete($,void 0,o),onRestrict:w=>{throw new he(w,"restrict")},onSetNull:(w,$,p)=>U.patch($,{[p]:null}),schema:d,tableName:r}),await Re(r),await Te(r),y&&E){const w={...E,[y]:L()},$=e.join(Object.keys(a.shape).map(p=>e`${e.identifier(p)} = ${H(w[p]??null)}`),e`, `);await Se(r,"UPDATE",$,_),await ce(r,E,w),await Z(r,t,E,void 0),await le(r,t,w,E),await X(r,t,"update",w),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E,table:r});return}await Se(r,"DELETE",void 0,_),ke.delete(t),await ce(r,E??void 0,void 0),await Z(r,t,E??void 0,void 0),await le(r,t,void 0),await X(r,t,"delete"),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E??void 0,table:r})}},async findFirst(t,n={}){return(await U.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const o=await U.findFirst(t,n);if(o===null)throw new zt(`findFirstOrThrow: no "${t}" document matched`);return o},async findMany(t,n={}){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Gt(n.orderBy),a=n.cursor?Vt(r,Yt(n.cursor)):void 0,_=Ye,E=async(N,D,K,ve)=>{if(Ge(N))return u?sn(u,N,D,K,ve):Ve(N);const be=d.tables[N];if(!be)throw new g("INTERNAL",`unknown table: ${N}`);const Ce=_e(be.softDeleteMode,void 0),ee={[D]:{in:K}},q=O(O(ee,ve),Ce),ue=await ge(q,N,void 0),Xe=$e(ue,R),ze=F(D);let fe=e`SELECT ${ze} AS __fk__, COUNT(*) AS count FROM ${e.identifier(N)}`;Xe&&(fe=e`${fe} WHERE ${Xe}`),fe=e`${fe} GROUP BY ${ze}`;const Ct=await C(i,c,fe),Je=new Map;for(const Qe of Ct)Je.set(Qe.__fk__,Number(Qe.count??0));return Je};let f=O(n.baseWhere,n.where);f=O(f,_e(o.softDeleteMode,n.includeDeleted)),f=await it(f,{fetcher:_,maxRelationKeys:h,relationBaseWhere:n.relationBaseWhere,schema:d,tableName:t}),a&&(f=f?{AND:[f,a]}:a);const y=$e(f,R),w=En(r);let $=e`SELECT * FROM ${e.identifier(t)}`;y&&($=e`${$} WHERE ${y}`),$=e`${$} ORDER BY ${w}`;const p=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;p!==void 0&&($=e`${$} LIMIT ${e.raw(String(p+1))}`);const S=await C(i,c,$),T=wn(o,S);if(p===void 0)return n.with&&await ot({fetcher:_,groupedCounter:E,parents:T,...rt(n),schema:d,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:st(T,n.select,n.with)};const I=T.length>p,k=I?T.slice(0,p):T,B=k.at(-1);return n.with&&await ot({fetcher:_,groupedCounter:E,parents:k,...rt(n),schema:d,tableName:t,with:n.with}),{continueCursor:I&&B?Xt(B,r):null,isDone:!I,page:st(k,n.select,n.with)}},async get(t,n){const o=await se(t,n);if(!o)return null;const r=d.tables[o];return r?ie(r,await bt.load(o,t)):null},async groupBy(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=n.agg??{op:"count"};if(we(r.op),r.op!=="count"&&!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);const a=_e(o.softDeleteMode,void 0),_=O(O(n.baseWhere,n.where),a),E=await ge(_,t,n.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!n.baseWhere&&!f&&!a){const T=await gt(t,o.aggregateIndexes,r,n);if(T!==void 0)return T}const y=$e(E,R),w=n.by.map(T=>e`${F(T)} AS ${e.identifier(T)}`);if(r.op==="count")w.push(e`COUNT(*) AS value`);else{if(!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);w.push(e`${e.raw(we(r.op))}(${F(r.field)}) AS value`)}const $=e.join(n.by.map(T=>F(T)),e`, `);let p=e`SELECT ${e.join(w,e`, `)} FROM ${e.identifier(t)}`;y&&(p=e`${p} WHERE ${y}`),p=e`${p} GROUP BY ${$}`;const S=await C(i,c,p);return mn(n.by,S)},async insert(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);await W();const a=yn(r,n,Y);De(r,a);let _,E=!0;o?.clientId!==void 0?(Ht(o.clientId),_=o.clientId):o?.allowExplicitId&&typeof a._id=="string"?_=a._id:(_=M(),E=!1);const f=o?.allowExplicitId&&typeof a._creationTime=="number"?a._creationTime:L(),y={...a,_creationTime:f,_id:_};P(t,"before","insert")&&await j("before","insert",{doc:{...y},id:_,op:"insert",table:t}),await Re(t),await Te(t);const{columns:w,values:$}=St(r,_,f,a);return await mt(t,e`INSERT INTO ${e.identifier(t)} (${te(w)}) VALUES (${re($)})`),E&&ke.set(_,t),await ce(t,void 0,y),await Z(t,_,void 0,y),await le(t,_,y),await X(t,_,"insert",y),P(t,"after","insert")&&await j("after","insert",{doc:y,id:_,op:"insert",table:t}),_},normalizeId(t,n){return Kt(d,t,n)},async patch(t,n,o){Ze("patch",n);const r=await se(t,o);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const a=d.tables[r];if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=await me(r,t),E=ie(a,_);if(!E)throw new g("INTERNAL",`document not found: ${t}`);const f={...E,...n,_id:t};ft(a,n,f,Y),De(a,f,!0),P(r,"before","update")&&await j("before","update",{doc:{...f},id:t,op:"update",previous:E,table:r}),await Re(r),await Te(r);const y=Object.keys(a.shape),w=e.join(y.map($=>e`${e.identifier($)} = ${H(f[$]??null)}`),e`, `);await Se(r,"UPDATE",w,_),await ce(r,E,f),await Z(r,t,E,f),await le(r,t,f,E),await X(r,t,"update",f),P(r,"after","update")&&await j("after","update",{doc:f,id:t,op:"update",previous:E,table:r})},async restore(t,n){const o=await se(t,n);if(!o)throw new g("INTERNAL",`document not found: ${t}`);const r=d.tables[o],a=r?.softDeleteMode?.field;if(!r||!a)throw new g("INTERNAL",`ctx.db.restore: table "${o}" is not a .softDelete() table`);const _=await me(o,t),E=_?.[a]!==null&&_?.[a]!==void 0;if(await U.patch(t,{[a]:null},n),E){const f=ie(r,_);f!==null&&await Z(o,t,void 0,{...f,[a]:null})}},query(t){const n=d.tables[t];if(!n)throw new g("INTERNAL",`unknown table: ${t}`);const o="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",r=[],a=f=>r.every(y=>y(f)),_=async(f,y)=>{await W();const w=r.length>0,$=await Dt(i,c,n,t,f,qt(w?void 0:y));if(!w)return y===void 0&&Ot($),$;const p=$.filter(S=>a(S));return y===void 0?p:p.slice(0,y)},E=f=>{const y={async*[Symbol.asyncIterator](){if(!f)throw new g("INTERNAL",o);yield*await _(f,void 0)},async collect(){if(!f)throw new g("INTERNAL",o);return _(f,void 0)},async collectWithScores(){throw new g("GLOBAL_SEARCH_SCORES_UNSUPPORTED",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(w){return r.push(w),y},async first(){if(!f)throw new g("INTERNAL",o);return(await _(f,1))[0]??null},order(){return y},async paginate(w){if(!f)throw new g("INTERNAL",o);const $=Nt(w);return Mt(await _(f,Ft($)),$)},async take(w){if(!f)throw new g("INTERNAL",o);return _(f,w)},async unique(){if(!f)throw new g("INTERNAL",o);const w=await _(f,2);if(w.length>1)throw new dn(`unique() on table "${t}" matched ${String(w.length)} documents; expected at most one`);return w[0]??null},withGeoIndex(){throw new g("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new g("INTERNAL",o)},withSearchIndex(w,$){const p=(n.searchIndexes??[]).find(T=>T.name===w);if(!p)throw new g("INTERNAL",`unknown search index "${w}" on table "${t}"`);const S={definition:p,field:p.field,filters:[],hasQuery:!1,indexName:w,query:""};if($(Lt(S,t,kt(p.language))),!S.hasQuery)throw new g("INTERNAL",`search index "${w}" on table "${t}" requires a .search(field, query) call`);return E(S)}};return y};return E(void 0)},async rank(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(D=>D.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(o.restrictsCounts)throw new nt(t);if(await W(),!await Me(t,a))return null;const E=typeof o.row=="string"?o.row:o.row._id;if(!E)return null;const f=ne(t,a.name),y=a.sortBy.map((D,K)=>Q(K)),w=te(["__partition__",...y]),p=(await C(i,c,e`SELECT ${w} FROM ${e.identifier(f)} WHERE ${e.identifier("__id__")} = ${E}`))[0];if(!p)return null;const S=p.__partition__,T=O(o.baseWhere,o.where);et(T,d,t,"rank");const I=tt(a,T);if(I&&Ie(a.partitionBy??[],I)!==S)return null;const k=gn(c.name,a,y,p,E),B=await C(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}${k?e` AND (${k})`:e``}`),N=await C(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(B[0]?.c??0)+1,total:Number(N[0]?.c??0)}},async rankPage(t,n,o={}){et(O(o.baseWhere,o.where),d,t,"rankPage");const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(q=>q.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await W(),!await Me(t,a))return{continueCursor:null,isDone:!0,page:[]};const E=ne(t,a.name),f=a.sortBy.map((q,ue)=>Q(ue)),y=Math.max(1,Math.min(1e3,Math.floor(o.take??100))),w=O(o.baseWhere,o.where),$=tt(a,w),p=bn(a,f),S=e.join(p.map(q=>e`${e.identifier(q.column)} ${e.raw(q.direction==="desc"?"DESC":"ASC")}`),e`, `),T=[];typeof o.partitionKey=="string"?T.push(e`${e.identifier("__partition__")} = ${o.partitionKey}`):$&&T.push(e`${e.identifier("__partition__")} = ${Ie(a.partitionBy??[],$)}`);const I=jt(o);if(I!==void 0){const q=vn(c.name,p,I);q!==void 0&&T.push(q)}const k=te([Ee,"__partition__",...f]);let B=e`SELECT ${k} FROM ${e.identifier(E)}`;T.length>0&&(B=e`${B} WHERE ${e.join(T,e` AND `)}`),B=e`${B} ORDER BY ${S} LIMIT ${e.raw(String(y+1))}`;const N=await C(i,c,B),D=N.length>y,K=D?N.slice(0,y):N,ve=K.map(q=>q[Ee]),be=await Cn(i,c,r,t,ve);let Ce=null;const ee=K.at(-1);if(D&&ee!==void 0){const q=[ee.__partition__,...f.map(ue=>ee[ue]),ee[Ee]];Ce=In(q)}return{continueCursor:Ce,isDone:!D,page:be}},async replace(t,n,o,r){Ze("replace",n);const a=await se(t,o);if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=d.tables[a];if(!_)throw new g("INTERNAL",`document not found: ${t}`);const E=await me(a,t);if(E===void 0)throw new g("INTERNAL",`document not found: ${t}`);const y=Pt(d,a,"update")||(_.aggregateIndexes??[]).length>0||(_.rankIndexes??[]).length>0?ie(_,E)??void 0:void 0,w=r?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:L(),$={...n,_creationTime:w,_id:t};ft(_,n,$,Y),De(_,$),P(a,"before","update")&&await j("before","update",{doc:{...$},id:t,op:"update",previous:y,table:a}),await Re(a),await Te(a);const p=Object.keys(_.shape),S=e.join([e`${e.identifier("_creationTime")} = ${w}`,...p.map(T=>e`${e.identifier(T)} = ${H($[T]??null)}`)],e`, `);await Se(a,"UPDATE",S,E),await ce(a,y,$),await Z(a,t,y,$),await le(a,t,$,y),await X(a,t,"update",$),P(a,"after","update")&&await j("after","update",{doc:$,id:t,op:"update",previous:y,table:a})}};return He={db:U,scheduler:yt},U};export{ii as backfillSqlSearchIndexes,ei as createSqlCtxDb,ri as decodeGlobalRow,Hn as readSqlCdcChangedTables,Zn as readSqlCdcChanges,Et as readSqlCdcFloor,Mn as runSqlAggregateMigrations,Wn as runSqlCdcMigration,Nn as runSqlGlobalTableMigrations,On as runSqlRankMigrations,At as runSqlSearchMigrations,Pn as sweepSqlCdcRetention};
|