@@ -143,7 +143,6 @@ import { connectionIdentifier } from "./connection-name-identifier";
143143import { annotateToolResultOutcome } from "./tool-result" ;
144144
145145const PLUGIN_STORAGE_DELETE_KEY_BATCH_SIZE = 90 ;
146- const PLUGIN_STORAGE_CREATE_ROW_BATCH_SIZE = 90 ;
147146const MAX_APPROVAL_ARGUMENT_PREVIEW_CHARS = 4_000 ;
148147
149148// ---------------------------------------------------------------------------
@@ -596,6 +595,14 @@ type LooseStorageDb = {
596595 tableName : string ,
597596 rows : readonly Record < string , unknown > [ ] ,
598597 ) => Promise < readonly unknown [ ] > ;
598+ readonly upsertMany : (
599+ tableName : string ,
600+ options : {
601+ readonly target : readonly string [ ] ;
602+ readonly update : readonly string [ ] ;
603+ readonly values : readonly Record < string , unknown > [ ] ;
604+ } ,
605+ ) => Promise < void > ;
599606 readonly deleteMany : ( tableName : string , options ?: unknown ) => Promise < void > ;
600607 readonly findFirst : (
601608 tableName : string ,
@@ -632,6 +639,19 @@ const makeCoreDb = (fuma: ReturnType<typeof makeFumaClient>) => ({
632639 : fuma
633640 . use ( `${ tableName } .createMany` , ( db ) => asLooseStorageDb ( db ) . createMany ( tableName , rows ) )
634641 . pipe ( Effect . asVoid ) ,
642+ upsertMany : < TName extends CoreTableName > (
643+ tableName : TName ,
644+ options : {
645+ readonly target : readonly string [ ] ;
646+ readonly update : readonly string [ ] ;
647+ readonly values : readonly Record < string , unknown > [ ] ;
648+ } ,
649+ ) : Effect . Effect < void , StorageFailure > =>
650+ options . values . length === 0
651+ ? Effect . void
652+ : fuma . use ( `${ tableName } .upsertMany` , ( db ) =>
653+ asLooseStorageDb ( db ) . upsertMany ( tableName , options ) ,
654+ ) ,
635655 deleteMany : < TName extends CoreTableName > (
636656 tableName : TName ,
637657 options : { readonly where ?: CoreWhere } = { } ,
@@ -981,33 +1001,22 @@ const makePluginStorageFacade = (input: {
9811001 const uniqueEntries = [ ...entriesById . values ( ) ] ;
9821002 if ( uniqueEntries . length === 0 ) return ;
9831003
984- yield * deleteManyImpl ( owner , os . subject , uniqueEntries ) ;
985-
9861004 const now = new Date ( ) ;
987- for (
988- let offset = 0 ;
989- offset < uniqueEntries . length ;
990- offset += PLUGIN_STORAGE_CREATE_ROW_BATCH_SIZE
991- ) {
992- const batchEntries = uniqueEntries . slice (
993- offset ,
994- offset + PLUGIN_STORAGE_CREATE_ROW_BATCH_SIZE ,
995- ) ;
996- yield * input . core . createMany (
997- "plugin_storage" ,
998- batchEntries . map ( ( entry ) => ( {
999- tenant,
1000- owner : os . owner ,
1001- subject : os . subject ,
1002- plugin_id : input . pluginId ,
1003- collection : entry . collection ,
1004- key : entry . key ,
1005- data : entry . data ,
1006- created_at : now ,
1007- updated_at : now ,
1008- } ) ) ,
1009- ) ;
1010- }
1005+ yield * input . core . upsertMany ( "plugin_storage" , {
1006+ target : [ "tenant" , "owner" , "subject" , "plugin_id" , "collection" , "key" ] ,
1007+ update : [ "data" , "updated_at" ] ,
1008+ values : uniqueEntries . map ( ( entry ) => ( {
1009+ tenant,
1010+ owner : os . owner ,
1011+ subject : os . subject ,
1012+ plugin_id : input . pluginId ,
1013+ collection : entry . collection ,
1014+ key : entry . key ,
1015+ data : entry . data ,
1016+ created_at : now ,
1017+ updated_at : now ,
1018+ } ) ) ,
1019+ } ) ;
10111020 } ) ;
10121021
10131022 const removeManyImpl = (
@@ -1104,10 +1113,24 @@ const makePluginStorageFacade = (input: {
11041113 PluginStorageEntry < PluginStorageCollectionData < typeof definition > > ,
11051114 StorageFailure
11061115 > ,
1116+ putMany : ( storageInput ) =>
1117+ putManyImpl (
1118+ storageInput . owner ,
1119+ storageInput . entries . map ( ( entry ) => ( {
1120+ collection : definition . name ,
1121+ key : entry . key ,
1122+ data : entry . data ,
1123+ } ) ) ,
1124+ ) ,
11071125 query : ( storageInput ) => queryCollection ( definition , storageInput ) ,
11081126 count : ( storageInput ) =>
11091127 queryCollection ( definition , storageInput ) . pipe ( Effect . map ( ( rows ) => rows . length ) ) ,
11101128 remove : ( storageInput ) => removeImpl ( storageInput . owner , definition . name , storageInput . key ) ,
1129+ removeMany : ( storageInput ) =>
1130+ removeManyImpl (
1131+ storageInput . owner ,
1132+ storageInput . keys . map ( ( key ) => ( { collection : definition . name , key } ) ) ,
1133+ ) ,
11111134 } ) ,
11121135 get : ( storageInput ) => getVisible ( storageInput . collection , storageInput . key ) ,
11131136 getForOwner : ( storageInput ) =>
0 commit comments