Skip to content

Commit 7752e0c

Browse files
committed
Added a batch update operation to DataSync
1 parent 65dfabd commit 7752e0c

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

IHP/DataSync/Controller.hs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,36 @@ instance (
208208
209209
case result of
210210
[record] -> sendJSON DidUpdateRecord { requestId, record }
211-
otherwise -> error "Unexpected result in CreateRecordMessage handler"
211+
otherwise -> error "Unexpected result in UpdateRecordMessage handler"
212+
213+
pure ()
214+
215+
handleMessage UpdateRecordsMessage { table, ids, patch, requestId } = do
216+
ensureRLSEnabled table
217+
218+
let columns = patch
219+
|> HashMap.keys
220+
|> map fieldNameToColumnName
221+
|> map PG.Identifier
222+
223+
let values = patch
224+
|> HashMap.elems
225+
|> map aesonValueToPostgresValue
226+
227+
let keyValues = zip columns values
228+
229+
let setCalls = keyValues
230+
|> map (\_ -> "? = ?")
231+
|> ByteString.intercalate ", "
232+
let query = "UPDATE ? SET " <> setCalls <> " WHERE id IN ? RETURNING *"
233+
234+
let params = [PG.toField (PG.Identifier table)]
235+
<> (join (map (\(key, value) -> [PG.toField key, value]) keyValues))
236+
<> [PG.toField (PG.In ids)]
237+
238+
records <- sqlQueryWithRLS (PG.Query query) params
239+
240+
sendJSON DidUpdateRecords { requestId, records }
212241
213242
pure ()
214243

IHP/DataSync/Types.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ data DataSyncMessage
1414
| CreateRecordMessage { table :: !Text, record :: !(HashMap Text Value), requestId :: !Int }
1515
| CreateRecordsMessage { table :: !Text, records :: ![HashMap Text Value], requestId :: !Int }
1616
| UpdateRecordMessage { table :: !Text, id :: !UUID, patch :: !(HashMap Text Value), requestId :: !Int }
17+
| UpdateRecordsMessage { table :: !Text, ids :: ![UUID], patch :: !(HashMap Text Value), requestId :: !Int }
1718
| DeleteRecordMessage { table :: !Text, id :: !UUID, requestId :: !Int }
1819
deriving (Eq, Show)
1920

@@ -29,6 +30,7 @@ data DataSyncResponse
2930
| DidCreateRecord { requestId :: !Int, record :: ![Field] } -- ^ Response to 'CreateRecordMessage'
3031
| DidCreateRecords { requestId :: !Int, records :: ![[Field]] } -- ^ Response to 'CreateRecordsMessage'
3132
| DidUpdateRecord { requestId :: !Int, record :: ![Field] } -- ^ Response to 'UpdateRecordMessage'
33+
| DidUpdateRecords { requestId :: !Int, records :: ![[Field]] } -- ^ Response to 'UpdateRecordsMessage'
3234
| DidDeleteRecord { requestId :: !Int }
3335

3436
data Subscription = Subscription { id :: !UUID, channelSubscription :: !PGListener.Subscription }

lib/IHP/DataSync/ihp-datasync.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,28 @@ export async function updateRecord(table, id, patch) {
376376
}
377377
}
378378

379+
export async function updateRecords(table, ids, patch) {
380+
if (typeof table !== "string") {
381+
throw new Error(`Table name needs to be a string, you passed ${JSON.stringify(table)} in a call to updateRecords(${JSON.stringify(table)}, ${JSON.stringify(ids)}, ${JSON.stringify(patch, null, 4)})`);
382+
}
383+
if (!Array.isArray(ids)) {
384+
throw new Error(`IDs need to be an array, you passed ${JSON.stringify(ids)} in a call to updateRecords(${JSON.stringify(table)}, ${JSON.stringify(ids)}, ${JSON.stringify(patch, null, 4)})`);
385+
}
386+
if (patch !== Object(patch)) {
387+
throw new Error(`Patch needs to be an object, you passed ${JSON.stringify(patch)} in a call to updateRecords(${JSON.stringify(table)}, ${JSON.stringify(ids)}, ${JSON.stringify(patch, null, 4)})`);
388+
}
389+
390+
const request = { tag: 'UpdateRecordsMessage', table, ids, patch };
391+
392+
try {
393+
const response = await DataSyncController.getInstance().sendMessage(request);
394+
395+
return response.records;
396+
} catch (e) {
397+
throw new Error(e.message);
398+
}
399+
}
400+
379401
export async function deleteRecord(table, id) {
380402
if (typeof table !== "string") {
381403
throw new Error(`Table name needs to be a string, you passed ${JSON.stringify(table)} in a call to deleteRecord(${JSON.stringify(table)}, ${JSON.stringify(id)})`);

0 commit comments

Comments
 (0)