@datastax/astra-db-ts
Version:
Data API TypeScript client
101 lines (100 loc) • 3.98 kB
JavaScript
// Copyright Datastax, Inc
// SPDX-License-Identifier: Apache-2.0
import { DataAPIResponseError } from '../../../documents/errors.js';
import { SerDesTarget } from '../../../lib/api/ser-des/ctx.js';
import { isNonEmpty } from '../../../lib/utils.js';
export const insertManyOrdered = async (httpClient, serdes, documents, chunkSize, timeoutManager, err) => {
const insertedIds = [];
for (let i = 0, n = documents.length; i < n; i += chunkSize) {
const slice = documents.slice(i, i + chunkSize);
const extraLogInfo = (documents.length === slice.length)
? { records: documents.length, ordered: true }
: { records: documents.length, slice: `${i}..${i + slice.length}`, ordered: true };
const resp = await insertMany(httpClient, serdes, slice, true, timeoutManager, extraLogInfo);
insertedIds.push(...resp.insertedIds);
if (resp.error) {
throw new err([resp.error], {
insertedIds: insertedIds,
insertedCount: insertedIds.length,
});
}
}
return insertedIds;
};
export const insertManyUnordered = async (httpClient, serdes, documents, concurrency, chunkSize, timeoutManager, err) => {
const insertedIds = [];
let masterIndex = 0;
const docResps = [];
const errors = [];
const promises = Array.from({ length: concurrency }, async () => {
while (masterIndex < documents.length) {
const localI = masterIndex;
const endIdx = Math.min(localI + chunkSize, documents.length);
masterIndex += chunkSize;
const slice = documents.slice(localI, endIdx);
const extraLogInfo = (documents.length === slice.length)
? { records: documents.length, ordered: false }
: { records: documents.length, slice: `${localI}..${endIdx}`, ordered: false };
const resp = await insertMany(httpClient, serdes, slice, false, timeoutManager, extraLogInfo);
insertedIds.push(...resp.insertedIds);
docResps.push(...resp.documentResponses);
if (resp.error) {
errors.push(resp.error);
}
}
});
await Promise.all(promises);
if (isNonEmpty(errors)) {
throw new err(errors, {
insertedIds: insertedIds,
insertedCount: insertedIds.length,
});
}
return insertedIds;
};
const insertMany = async (httpClient, serdes, documents, ordered, timeoutManager, extraLogInfo) => {
let raw, err;
try {
const serialized = [];
let bigNumsPresent = false;
for (let i = 0, n = documents.length; i < n; i++) {
const resp = serdes.serialize(documents[i], SerDesTarget.Record);
serialized.push(resp[0]);
bigNumsPresent || (bigNumsPresent = resp[1]);
}
raw = await httpClient.executeCommand({
insertMany: {
documents: serialized,
options: {
returnDocumentResponses: true,
ordered,
},
},
}, { timeoutManager, bigNumsPresent, extraLogInfo: extraLogInfo });
}
catch (e) {
if (!(e instanceof DataAPIResponseError)) {
throw e;
}
raw = e.rawResponse;
err = e;
}
const documentResponses = raw.status?.documentResponses ?? [];
const errors = raw.errors;
const insertedIds = [];
for (let i = 0, n = documentResponses.length; i < n; i++) {
const response = documentResponses[i];
if (response.status === "OK") {
insertedIds.push(serdes.deserialize(response._id, raw, SerDesTarget.InsertedId));
}
else if ('errorsIdx' in response) {
response.error = errors[response.errorsIdx];
delete response.errorsIdx;
}
}
return {
documentResponses,
insertedIds,
error: err,
};
};