11import * as _syscalls1_0 from 'spacetime:sys@1.0' ;
22import * as _syscalls1_2 from 'spacetime:sys@1.2' ;
3+ import * as _syscalls1_3 from 'spacetime:sys@1.3' ;
34
45import type { ModuleHooks , u16 , u32 } from 'spacetime:sys@1.0' ;
56import { AlgebraicType , ProductType } from '../lib/algebraic_type' ;
@@ -48,7 +49,9 @@ import ViewResultHeader from '../lib/autogen/view_result_header_type';
4849
4950const { freeze } = Object ;
5051
51- export const sys = freeze ( wrapSyscalls ( _syscalls1_0 , _syscalls1_2 ) ) ;
52+ export const sys = freeze (
53+ wrapSyscalls ( _syscalls1_0 , _syscalls1_2 , _syscalls1_3 )
54+ ) ;
5255
5356export function parseJsonObject ( json : string ) : JsonObject {
5457 let value : unknown ;
@@ -220,10 +223,8 @@ export const hooks: ModuleHooks = {
220223 return writer . getBuffer ( ) ;
221224 } ,
222225 __call_reducer__ ( reducerId , sender , connId , timestamp , argsBuf ) {
223- const argsType = AlgebraicType . Product (
224- MODULE_DEF . reducers [ reducerId ] . params
225- ) ;
226- const args = AlgebraicType . deserializeValue (
226+ const argsType = MODULE_DEF . reducers [ reducerId ] . params ;
227+ const args = ProductType . deserializeValue (
227228 new BinaryReader ( argsBuf ) ,
228229 argsType ,
229230 MODULE_DEF . typespace
@@ -499,15 +500,30 @@ function makeTableView(
499500 prefix : any [ ] ,
500501 prefix_elems : number
501502 ) => {
502- if ( prefix_elems > numColumns - 1 )
503- throw new TypeError ( 'too many elements in prefix' ) ;
504503 for ( let i = 0 ; i < prefix_elems ; i ++ ) {
505504 const elemType = indexType . value . elements [ i ] . algebraicType ;
506505 AlgebraicType . serializeValue ( writer , elemType , prefix [ i ] , typespace ) ;
507506 }
508507 return writer ;
509508 } ;
510509
510+ const serializePoint = ( colVal : any [ ] ) : Uint8Array => {
511+ const writer = new BinaryWriter ( baseSize ) ;
512+ serializePrefix ( writer , colVal , numColumns ) ;
513+ return writer . getBuffer ( ) ;
514+ } ;
515+
516+ const singleElement =
517+ numColumns === 1 ? indexType . value . elements [ 0 ] . algebraicType : null ;
518+
519+ const serializeSinglePoint =
520+ singleElement &&
521+ ( ( colVal : any ) : Uint8Array => {
522+ const writer = new BinaryWriter ( baseSize ) ;
523+ AlgebraicType . serializeValue ( writer , singleElement , colVal , typespace ) ;
524+ return writer . getBuffer ( ) ;
525+ } ) ;
526+
511527 type IndexScanArgs = [
512528 prefix : Uint8Array ,
513529 prefix_elems : u16 ,
@@ -516,33 +532,51 @@ function makeTableView(
516532 ] ;
517533
518534 let index : Index < any , any > ;
519- if ( isUnique ) {
520- const serializeBound = ( colVal : any [ ] ) : IndexScanArgs => {
521- if ( colVal . length !== numColumns )
522- throw new TypeError ( 'wrong number of elements' ) ;
523-
524- const writer = new BinaryWriter ( baseSize + 1 ) ;
525- const prefix_elems = numColumns - 1 ;
526- serializePrefix ( writer , colVal , prefix_elems ) ;
527- const rstartOffset = writer . offset ;
528- writer . writeU8 ( 0 ) ;
529- AlgebraicType . serializeValue (
530- writer ,
531- indexType . value . elements [ numColumns - 1 ] . algebraicType ,
532- colVal [ numColumns - 1 ] ,
533- typespace
534- ) ;
535- const buffer = writer . getBuffer ( ) ;
536- const prefix = buffer . slice ( 0 , rstartOffset ) ;
537- const rstart = buffer . slice ( rstartOffset ) ;
538- return [ prefix , prefix_elems , rstart , rstart ] ;
539- } ;
535+ if ( isUnique && serializeSinglePoint ) {
536+ index = {
537+ find : ( colVal : IndexVal < any , any > ) : RowType < any > | null => {
538+ const point = serializeSinglePoint ( colVal ) ;
539+ const iter = tableIterator (
540+ sys . datastore_index_scan_point_bsatn ( index_id , point ) ,
541+ rowType
542+ ) ;
543+ const { value, done } = iter . next ( ) ;
544+ if ( done ) return null ;
545+ if ( ! iter . next ( ) . done )
546+ throw new Error (
547+ '`datastore_index_scan_range_bsatn` on unique field cannot return >1 rows'
548+ ) ;
549+ return value ;
550+ } ,
551+ delete : ( colVal : IndexVal < any , any > ) : boolean => {
552+ const point = serializeSinglePoint ( colVal ) ;
553+ const num = sys . datastore_delete_by_index_scan_point_bsatn (
554+ index_id ,
555+ point
556+ ) ;
557+ return num > 0 ;
558+ } ,
559+ update : ( row : RowType < any > ) : RowType < any > => {
560+ const writer = new BinaryWriter ( baseSize ) ;
561+ AlgebraicType . serializeValue ( writer , rowType , row , typespace ) ;
562+ const ret_buf = sys . datastore_update_bsatn (
563+ table_id ,
564+ index_id ,
565+ writer . getBuffer ( )
566+ ) ;
567+ integrateGeneratedColumns ?.( row , ret_buf ) ;
568+ return row ;
569+ } ,
570+ } as UniqueIndex < any , any > ;
571+ } else if ( isUnique ) {
540572 index = {
541573 find : ( colVal : IndexVal < any , any > ) : RowType < any > | null => {
542- if ( numColumns === 1 ) colVal = [ colVal ] ;
543- const args = serializeBound ( colVal ) ;
574+ if ( colVal . length !== numColumns )
575+ throw new TypeError ( 'wrong number of elements' ) ;
576+
577+ const point = serializePoint ( colVal ) ;
544578 const iter = tableIterator (
545- sys . datastore_index_scan_range_bsatn ( index_id , ... args ) ,
579+ sys . datastore_index_scan_point_bsatn ( index_id , point ) ,
546580 rowType
547581 ) ;
548582 const { value, done } = iter . next ( ) ;
@@ -554,11 +588,13 @@ function makeTableView(
554588 return value ;
555589 } ,
556590 delete : ( colVal : IndexVal < any , any > ) : boolean => {
557- if ( numColumns === 1 ) colVal = [ colVal ] ;
558- const args = serializeBound ( colVal ) ;
559- const num = sys . datastore_delete_by_index_scan_range_bsatn (
591+ if ( colVal . length !== numColumns )
592+ throw new TypeError ( 'wrong number of elements' ) ;
593+
594+ const point = serializePoint ( colVal ) ;
595+ const num = sys . datastore_delete_by_index_scan_point_bsatn (
560596 index_id ,
561- ... args
597+ point
562598 ) ;
563599 return num > 0 ;
564600 } ,
@@ -574,6 +610,23 @@ function makeTableView(
574610 return row ;
575611 } ,
576612 } as UniqueIndex < any , any > ;
613+ } else if ( serializeSinglePoint ) {
614+ index = {
615+ filter : ( range : any ) : IteratorObject < RowType < any > > => {
616+ const point = serializeSinglePoint ( range ) ;
617+ return tableIterator (
618+ sys . datastore_index_scan_point_bsatn ( index_id , point ) ,
619+ rowType
620+ ) ;
621+ } ,
622+ delete : ( range : any ) : u32 => {
623+ const point = serializeSinglePoint ( range ) ;
624+ return sys . datastore_delete_by_index_scan_point_bsatn (
625+ index_id ,
626+ point
627+ ) ;
628+ } ,
629+ } as RangedIndex < any , any > ;
577630 } else {
578631 const serializeRange = ( range : any [ ] ) : IndexScanArgs => {
579632 if ( range . length > numColumns ) throw new TypeError ( 'too many elements' ) ;
@@ -613,21 +666,35 @@ function makeTableView(
613666 return [ prefix , prefix_elems , rstart , rend ] ;
614667 } ;
615668 index = {
616- filter : ( range : any ) : IteratorObject < RowType < any > > => {
617- if ( numColumns === 1 ) range = [ range ] ;
618- const args = serializeRange ( range ) ;
619- return tableIterator (
620- sys . datastore_index_scan_range_bsatn ( index_id , ...args ) ,
621- rowType
622- ) ;
669+ filter : ( range : any [ ] ) : IteratorObject < RowType < any > > => {
670+ if ( range . length === numColumns ) {
671+ const point = serializePoint ( range ) ;
672+ return tableIterator (
673+ sys . datastore_index_scan_point_bsatn ( index_id , point ) ,
674+ rowType
675+ ) ;
676+ } else {
677+ const args = serializeRange ( range ) ;
678+ return tableIterator (
679+ sys . datastore_index_scan_range_bsatn ( index_id , ...args ) ,
680+ rowType
681+ ) ;
682+ }
623683 } ,
624- delete : ( range : any ) : u32 => {
625- if ( numColumns === 1 ) range = [ range ] ;
626- const args = serializeRange ( range ) ;
627- return sys . datastore_delete_by_index_scan_range_bsatn (
628- index_id ,
629- ...args
630- ) ;
684+ delete : ( range : any [ ] ) : u32 => {
685+ if ( range . length === numColumns ) {
686+ const point = serializePoint ( range ) ;
687+ return sys . datastore_delete_by_index_scan_point_bsatn (
688+ index_id ,
689+ point
690+ ) ;
691+ } else {
692+ const args = serializeRange ( range ) ;
693+ return sys . datastore_delete_by_index_scan_range_bsatn (
694+ index_id ,
695+ ...args
696+ ) ;
697+ }
631698 } ,
632699 } as RangedIndex < any , any > ;
633700 }
0 commit comments