///
///
///
/**
* @file Manages query for records in Salesforce
* @author Shinichi Tomita
*/
import { EventEmitter } from 'events';
import { Logger } from './util/logger';
import { Serializable } from './record-stream';
import Connection from './connection';
import { QueryConfig as SOQLQueryConfig, SortDir } from './soql-builder';
import { Record, Optional, Schema, SObjectNames, ChildRelationshipNames, ChildRelationshipSObjectName, FieldProjectionConfig, FieldPathSpecifier, FieldPathScopedProjection, SObjectRecord, SObjectInputRecord, SaveResult, DateString, SObjectChildRelationshipProp, SObjectFieldNames } from './types';
import { Readable } from 'stream';
import SfDate from './date';
/**
*
*/
export type QueryField, FP extends FieldPathSpecifier = FieldPathSpecifier> = FP | FP[] | string | string[] | {
[field: string]: number | boolean;
};
/**
*
*/
type CValue = T extends DateString ? SfDate : T extends string | number | boolean ? T : never;
type CondOp = ['$eq', CValue | null] | ['$ne', CValue | null] | ['$gt', CValue] | ['$gte', CValue] | ['$lt', CValue] | ['$lte', CValue] | ['$like', T extends string ? T : never] | ['$nlike', T extends string ? T : never] | ['$in', Array>] | ['$nin', Array>] | ['$includes', T extends string ? T[] : never] | ['$excludes', T extends string ? T[] : never] | ['$exists', boolean];
type CondValueObj[0]> = Op extends CondOp[0] ? Op extends string ? {
[K in Op]: Extract, [Op, any]>[1];
} : never : never;
type CondValue = CValue | Array> | null | CondValueObj;
type ConditionSet = {
[K in keyof R]?: CondValue;
};
export type QueryCondition> = {
$or: Array>;
} | {
$and: Array>;
} | ConditionSet>;
export type QuerySort, R extends SObjectRecord = SObjectRecord> = {
[K in keyof R]?: SortDir;
} | Array<[keyof R, SortDir]>;
/**
*
*/
export type QueryConfig, FP extends FieldPathSpecifier = FieldPathSpecifier> = {
fields?: QueryField;
includes?: {
[CRN in ChildRelationshipNames]?: QueryConfig>;
};
table?: string;
conditions?: QueryCondition;
sort?: QuerySort;
limit?: number;
offset?: number;
};
export type QueryOptions = {
headers: {
[name: string]: string;
};
maxFetch: number;
autoFetch: boolean;
scanAll: boolean;
responseTarget: QueryResponseTarget;
};
export type QueryResult = {
done: boolean;
totalSize: number;
records: R[];
nextRecordsUrl?: string;
};
export type QueryExplainResult = {
plans: Array<{
cardinality: number;
fields: string[];
leadingOperationType: 'Index' | 'Other' | 'Sharing' | 'TableScan';
notes: Array<{
description: string;
fields: string[];
tableEnumOrId: string;
}>;
relativeCost: number;
sobjectCardinality: number;
sobjectType: string;
}>;
};
declare const ResponseTargetValues: readonly ["QueryResult", "Records", "SingleRecord", "Count"];
export type QueryResponseTarget = typeof ResponseTargetValues[number];
export declare const ResponseTargets: {
[K in QueryResponseTarget]: K;
};
export type QueryResponse = QRT extends 'QueryResult' ? QueryResult : QRT extends 'Records' ? R[] : QRT extends 'SingleRecord' ? R | null : number;
export type BulkApiVersion = 1 | 2;
export type QueryDestroyOptions = {
allowBulk?: boolean;
bulkThreshold?: number;
bulkApiVersion?: BulkApiVersion;
};
export type QueryUpdateOptions = {
allowBulk?: boolean;
bulkThreshold?: number;
bulkApiVersion?: BulkApiVersion;
/**
* Skip record template evaluation.
*/
skipRecordTemplateEval?: boolean;
};
/**
* Query
*/
export declare class Query, R extends Record = Record, QRT extends QueryResponseTarget = QueryResponseTarget> extends EventEmitter {
static _logger: Logger;
_conn: Connection;
_logger: Logger;
_soql: Optional;
_locator: Optional;
_config: SOQLQueryConfig;
_children: Array>;
_options: QueryOptions;
_executed: boolean;
_finished: boolean;
_chaining: boolean;
_promise: Promise>;
_stream: Serializable;
totalSize: number;
totalFetched: number;
records: R[];
/**
*
*/
constructor(conn: Connection, config: string | QueryConfig | {
locator: string;
}, options?: Partial);
/**
* Select fields to include in the returning result
*/
select = FieldPathSpecifier, FPC extends FieldProjectionConfig = FieldPathScopedProjection, R2 extends SObjectRecord = SObjectRecord>(fields?: QueryField): Query;
/**
* Set query conditions to filter the result records
*/
where(conditions: QueryCondition | string): this;
/**
* Limit the returning result
*/
limit(limit: number): this;
/**
* Skip records
*/
skip(offset: number): this;
/**
* Synonym of Query#skip()
*/
offset: (offset: number) => this;
/**
* Set query sort with direction
*/
sort(sort: QuerySort | string): this;
sort(sort: SObjectFieldNames | string, dir: SortDir): this;
/**
* Synonym of Query#sort()
*/
orderby: typeof Query.prototype.sort;
/**
* Include child relationship query and move down to the child query context
*/
include, CN extends ChildRelationshipSObjectName, CFP extends FieldPathSpecifier = FieldPathSpecifier, CFPC extends FieldProjectionConfig = FieldPathScopedProjection, CR extends Record = SObjectRecord>(childRelName: CRN, conditions?: Optional>, fields?: Optional>, options?: {
limit?: number;
offset?: number;
sort?: QuerySort;
}): SubQuery;
include, CN extends SObjectNames, CR extends Record = SObjectRecord>(childRelName: string, conditions?: Optional>, fields?: Optional>, options?: {
limit?: number;
offset?: number;
sort?: QuerySort;
}): SubQuery;
/**
* Include child relationship queries, but not moving down to the children context
*/
includeChildren(includes: {
[CRN in ChildRelationshipNames]?: QueryConfig>;
}): this;
/**
* Setting maxFetch query option
*/
maxFetch(maxFetch: number): this;
/**
* Switching auto fetch mode
*/
autoFetch(autoFetch: boolean): this;
/**
* Set flag to scan all records including deleted and archived.
*/
scanAll(scanAll: boolean): this;
/**
*
*/
setResponseTarget(responseTarget: QRT1): Query;
/**
* Execute query and fetch records from server.
*/
execute(options_?: Partial & {
responseTarget?: QRT1;
}): Query;
/**
* Synonym of Query#execute()
*/
exec: (options_?: Partial & {
responseTarget?: QRT1 | undefined;
}) => Query;
/**
* Synonym of Query#execute()
*/
run: (options_?: Partial & {
responseTarget?: QRT1 | undefined;
}) => Query;
private locatorToUrl;
private urlToLocator;
private constructResponse;
/**
* @private
*/
_execute(options: QueryOptions): Promise>;
/**
* Obtain readable stream instance
*/
stream(type: 'record'): Serializable;
stream(type: 'csv'): Readable;
/**
* Pipe the queried records to another stream
* This is for backward compatibility; Query is not a record stream instance anymore in 2.0.
* If you want a record stream instance, use `Query#stream('record')`.
*/
pipe(stream: NodeJS.WritableStream): NodeJS.WritableStream;
/**
* @protected
*/
_expandFields(sobject_?: string): Promise;
/**
*
*/
_findRelationObject(relName: string): Promise;
/**
*
*/
_expandAsteriskFields(sobject: string, fields: string[]): Promise;
/**
*
*/
_expandAsteriskField(sobject: string, field: string): Promise;
/**
* Explain plan for executing query
*/
explain(): Promise;
/**
* Return SOQL expression for the query
*/
toSOQL(): Promise;
/**
* Promise/A+ interface
* http://promises-aplus.github.io/promises-spec/
*
* Delegate to deferred promise, return promise instance for query result
*/
then(onResolve?: ((qr: QueryResponse) => U | Promise) | null | undefined, onReject?: ((err: Error) => V | Promise) | null | undefined): Promise;
catch(onReject: (err: Error) => QueryResponse | Promise>): Promise>;
promise(): Promise>;
/**
* Bulk delete queried records
*/
destroy(options?: QueryDestroyOptions): Promise;
destroy(type: N, options?: QueryDestroyOptions): Promise;
/**
* Synonym of Query#destroy()
*/
delete: {
(options?: QueryDestroyOptions | undefined): Promise;
(type: N, options?: QueryDestroyOptions | undefined): Promise;
};
/**
* Synonym of Query#destroy()
*/
del: {
(options?: QueryDestroyOptions | undefined): Promise;
(type: N, options?: QueryDestroyOptions | undefined): Promise;
};
/**
* Bulk update queried records, using given mapping function/object
*/
update>(mapping: ((rec: R) => UR) | UR, type: N, options?: QueryUpdateOptions): Promise;
update>(mapping: ((rec: R) => UR) | UR, options?: QueryUpdateOptions): Promise;
private mapBulkV2ResultsToSaveResults;
/**
* Fetches all records for a subquery field by following nextRecordsUrl
* @private
*/
private _fetchAllSubqueryRecords;
}
/**
* SubQuery object for representing child relationship query
*/
export declare class SubQuery, PR extends Record, PQRT extends QueryResponseTarget, CRN extends ChildRelationshipNames = ChildRelationshipNames, CN extends SObjectNames = ChildRelationshipSObjectName, CR extends Record = Record> {
_relName: CRN;
_query: Query;
_parent: Query;
/**
*
*/
constructor(conn: Connection, relName: CRN, config: QueryConfig, parent: Query);
/**
*
*/
select = FieldPathSpecifier, FPC extends FieldProjectionConfig = FieldPathScopedProjection>(fields: QueryField): SubQuery>;
/**
*
*/
where(conditions: QueryCondition | string): this;
/**
* Limit the returning result
*/
limit(limit: number): this;
/**
* Skip records
*/
skip(offset: number): this;
/**
* Synonym of SubQuery#skip()
*/
offset: (offset: number) => this;
/**
* Set query sort with direction
*/
sort(sort: QuerySort): this;
sort(sort: string | SObjectFieldNames, dir: SortDir): this;
/**
* Synonym of SubQuery#sort()
*/
orderby: typeof SubQuery.prototype.sort;
/**
*
*/
_expandFields(): Promise;
/**
* Back the context to parent query object
*/
end = SObjectChildRelationshipProp, PR1 extends Record = PR & CRP>(): Query;
}
export default Query;