ravendb
Version:
RavenDB client for Node.js
254 lines • 10.4 kB
JavaScript
import { RavenCommand } from "../../Http/RavenCommand.js";
import { getHeaders } from "../../Utility/HttpUtil.js";
import { TypeUtil } from "../../Utility/TypeUtil.js";
import { throwError } from "../../Exceptions/index.js";
import { COUNTERS } from "../../Constants.js";
import { HashCalculator } from "../Queries/HashCalculator.js";
import { DateUtil } from "../../Utility/DateUtil.js";
import { readToEnd } from "../../Utility/StreamUtil.js";
import { ObjectUtil } from "../../Utility/ObjectUtil.js";
export class GetDocumentsCommand extends RavenCommand {
_id;
_ids;
_includes;
_counters;
_includeAllCounters;
_txMode;
_timeSeriesIncludes;
_revisionsIncludeByChangeVector;
_revisionsIncludeByDateTime;
_compareExchangeValueIncludes;
_metadataOnly;
_startsWith;
_matches;
_start;
_pageSize;
_exclude;
_startAfter;
_conventions;
constructor(opts) {
super();
this._conventions = opts.conventions;
// eslint-disable-next-line no-prototype-builtins
if (opts.hasOwnProperty("id")) {
opts = opts;
if (!opts.id) {
throwError("InvalidArgumentException", "id cannot be null");
}
this._id = opts.id;
this._includes = opts.includes;
this._metadataOnly = opts.metadataOnly;
// eslint-disable-next-line no-prototype-builtins
}
else if (opts.hasOwnProperty("ids")) {
opts = opts;
if (!opts.ids || opts.ids.length === 0) {
throwError("InvalidArgumentException", "Please supply at least one id");
}
this._ids = opts.ids;
this._includes = opts.includes;
this._metadataOnly = opts.metadataOnly;
this._timeSeriesIncludes = opts.timeSeriesIncludes;
this._compareExchangeValueIncludes = opts.compareExchangeValueIncludes;
this._revisionsIncludeByDateTime = opts.revisionIncludeByDateTimeBefore;
this._revisionsIncludeByChangeVector = opts.revisionsIncludesByChangeVector;
// eslint-disable-next-line no-prototype-builtins
}
else if (opts.hasOwnProperty("start") && opts.hasOwnProperty("pageSize")) {
opts = opts;
this._start = opts.start;
this._pageSize = opts.pageSize;
// eslint-disable-next-line no-prototype-builtins
if (opts.hasOwnProperty("startsWith")) {
if (!opts.startsWith) {
throwError("InvalidArgumentException", "startWith cannot be null");
}
this._startsWith = opts.startsWith;
this._startAfter = opts.startsAfter;
this._matches = opts.matches;
this._exclude = opts.exclude;
this._metadataOnly = opts.metadataOnly;
}
}
// eslint-disable-next-line no-prototype-builtins
if (opts.hasOwnProperty("includeAllCounters")) {
this._includeAllCounters = opts.includeAllCounters;
}
// eslint-disable-next-line no-prototype-builtins
if (opts.hasOwnProperty("counterIncludes")) {
const counters = opts.counterIncludes;
if (!counters) {
throwError("InvalidArgumentException", "CounterIncludes cannot be null.");
}
this._counters = counters;
}
}
createRequest(node) {
const uriPath = `${node.url}/databases/${node.database}/docs?`;
let query = "";
if (this._txMode === "ClusterWide") {
query += "&txMode=ClusterWide";
}
if (!TypeUtil.isNullOrUndefined(this._start)) {
query += `&start=${this._start}`;
}
if (this._pageSize) {
query += `&pageSize=${this._pageSize}`;
}
if (this._metadataOnly) {
query += "&metadataOnly=true";
}
if (this._startsWith) {
query += `&startsWith=${encodeURIComponent(this._startsWith)}`;
if (this._matches) {
query += `&matches=${encodeURIComponent(this._matches)}`;
}
if (this._exclude) {
query += `&exclude=${encodeURIComponent(this._exclude)}`;
}
if (this._startAfter) {
query += `&startAfter=${this._startAfter}`;
}
}
if (this._includes) {
for (const include of this._includes) {
query += `&include=${encodeURIComponent(include)}`;
}
}
if (this._includeAllCounters) {
query += `&counter=${COUNTERS.ALL}`;
}
else if (this._counters && this._counters.length) {
for (const counter of this._counters) {
query += `&counter=${encodeURIComponent(counter)}`;
}
}
if (this._timeSeriesIncludes) {
for (const tsInclude of this._timeSeriesIncludes) {
if ("from" in tsInclude) {
const range = tsInclude;
query += "×eries=" + this._urlEncode(range.name)
+ "&from=" + (range.from ? DateUtil.utc.stringify(range.from) : "")
+ "&to=" + (range.to ? DateUtil.utc.stringify(range.to) : "");
}
else if ("time" in tsInclude) {
const timeRange = tsInclude;
query +=
"×eriestime="
+ this._urlEncode(timeRange.name)
+ "&timeType="
+ this._urlEncode(timeRange.type)
+ "&timeValue="
+ timeRange.time.value
+ "&timeUnit="
+ this._urlEncode(timeRange.time.unit);
}
else if ("count" in tsInclude) {
const countRange = tsInclude;
query +=
"×eriescount="
+ this._urlEncode(countRange.name)
+ "&countType="
+ this._urlEncode(countRange.type)
+ "&countValue="
+ countRange.count;
}
else {
throwError("InvalidArgumentException", "Unexpected TimeSeries range: " + tsInclude);
}
}
}
if (this._revisionsIncludeByChangeVector) {
for (const changeVector of this._revisionsIncludeByChangeVector) {
query += "&revisions=" + this._urlEncode(changeVector);
}
}
if (this._revisionsIncludeByDateTime) {
query += "&revisionsBefore=" + this._urlEncode(DateUtil.utc.stringify(this._revisionsIncludeByDateTime));
}
if (this._compareExchangeValueIncludes) {
for (const compareExchangeValue of this._compareExchangeValueIncludes) {
query += "&cmpxchg=" + this._urlEncode(compareExchangeValue);
}
}
let request = { method: "GET", uri: uriPath + query };
if (this._id) {
request.uri += `&id=${encodeURIComponent(this._id)}`;
}
else if (this._ids) {
request = this.prepareRequestWithMultipleIds(request, this._ids);
}
return request;
}
prepareRequestWithMultipleIds(request, ids) {
const uniqueIds = new Set(ids);
// if it is too big, we fallback to POST (note that means that we can't use the HTTP cache any longer)
// we are fine with that, requests to load > 1024 items are going to be rare
const isGet = Array.from(uniqueIds)
.filter(x => x)
.map(x => x.length)
.reduce((result, next) => result + next, 0) < 1024;
let newUri = request.uri;
if (isGet) {
for (const x of uniqueIds) {
newUri += `&id=${encodeURIComponent(x || "")}`;
}
return { method: "GET", uri: newUri };
}
else {
const body = this._serializer
.serialize({ ids: [...uniqueIds] });
const calculateHash = GetDocumentsCommand._calculateHash(uniqueIds);
newUri += `&loadHash=${encodeURIComponent(calculateHash)}`;
return {
uri: newUri,
method: "POST",
headers: getHeaders()
.typeAppJson()
.build(),
body
};
}
}
static _calculateHash(uniqueIds) {
const hasher = new HashCalculator();
for (const x of uniqueIds) {
hasher.write(x);
}
return hasher.getHash();
}
async setResponseAsync(bodyStream, fromCache) {
if (!bodyStream) {
this.result = null;
return;
}
let body = null;
this.result =
await GetDocumentsCommand.parseDocumentsResultResponseAsync(bodyStream, this._conventions, b => body = b);
return body;
}
static async parseDocumentsResultResponseAsync(bodyStream, conventions, bodyCallback) {
const body = await readToEnd(bodyStream);
bodyCallback?.(body);
const parsedJson = JSON.parse(body);
return GetDocumentsCommand._mapToLocalObject(parsedJson, conventions);
}
static _mapToLocalObject(json, conventions) {
return {
results: json.Results.map(x => ObjectUtil.transformDocumentKeys(x, conventions)),
includes: ObjectUtil.mapIncludesToLocalObject(json.Includes, conventions),
compareExchangeValueIncludes: ObjectUtil.mapCompareExchangeToLocalObject(json.CompareExchangeValueIncludes),
timeSeriesIncludes: ObjectUtil.mapTimeSeriesIncludesToLocalObject(json.TimeSeriesIncludes),
counterIncludes: ObjectUtil.mapCounterIncludesToLocalObject(json.CounterIncludes),
revisionIncludes: json.RevisionIncludes,
nextPageStart: json.NextPageStart
};
}
get isReadRequest() {
return true;
}
set transactionMode(mode) {
this._txMode = mode;
}
}
//# sourceMappingURL=GetDocumentsCommand.js.map