Make QueryBuilder vars private
This commit is contained in:
parent
06245fee98
commit
a91e4b4da1
|
@ -44,23 +44,23 @@ export function removeKeyNumbering(key: any): string {
|
||||||
* Optionally takes a base lucene query object.
|
* Optionally takes a base lucene query object.
|
||||||
*/
|
*/
|
||||||
export class QueryBuilder<T> {
|
export class QueryBuilder<T> {
|
||||||
dbName: string
|
#dbName: string
|
||||||
index: string
|
#index: string
|
||||||
query: SearchFilters
|
#query: SearchFilters
|
||||||
limit: number
|
#limit: number
|
||||||
sort?: string
|
#sort?: string
|
||||||
bookmark?: string
|
#bookmark?: string
|
||||||
sortOrder: string
|
#sortOrder: string
|
||||||
sortType: string
|
#sortType: string
|
||||||
#includeDocs: boolean
|
#includeDocs: boolean
|
||||||
version?: string
|
#version?: string
|
||||||
indexBuilder?: () => Promise<any>
|
#indexBuilder?: () => Promise<any>
|
||||||
noEscaping = false
|
#noEscaping = false
|
||||||
|
|
||||||
constructor(dbName: string, index: string, base?: SearchFilters) {
|
constructor(dbName: string, index: string, base?: SearchFilters) {
|
||||||
this.dbName = dbName
|
this.#dbName = dbName
|
||||||
this.index = index
|
this.#index = index
|
||||||
this.query = {
|
this.#query = {
|
||||||
allOr: false,
|
allOr: false,
|
||||||
string: {},
|
string: {},
|
||||||
fuzzy: {},
|
fuzzy: {},
|
||||||
|
@ -75,65 +75,65 @@ export class QueryBuilder<T> {
|
||||||
containsAny: {},
|
containsAny: {},
|
||||||
...base,
|
...base,
|
||||||
}
|
}
|
||||||
this.limit = 50
|
this.#limit = 50
|
||||||
this.sortOrder = "ascending"
|
this.#sortOrder = "ascending"
|
||||||
this.sortType = "string"
|
this.#sortType = "string"
|
||||||
this.#includeDocs = true
|
this.#includeDocs = true
|
||||||
}
|
}
|
||||||
|
|
||||||
disableEscaping() {
|
disableEscaping() {
|
||||||
this.noEscaping = true
|
this.#noEscaping = true
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setIndexBuilder(builderFn: () => Promise<any>) {
|
setIndexBuilder(builderFn: () => Promise<any>) {
|
||||||
this.indexBuilder = builderFn
|
this.#indexBuilder = builderFn
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setVersion(version?: string) {
|
setVersion(version?: string) {
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
this.version = version
|
this.#version = version
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setTable(tableId: string) {
|
setTable(tableId: string) {
|
||||||
this.query.equal!.tableId = tableId
|
this.#query.equal!.tableId = tableId
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setLimit(limit?: number) {
|
setLimit(limit?: number) {
|
||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
this.limit = limit
|
this.#limit = limit
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setSort(sort?: string) {
|
setSort(sort?: string) {
|
||||||
if (sort != null) {
|
if (sort != null) {
|
||||||
this.sort = sort
|
this.#sort = sort
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setSortOrder(sortOrder?: string) {
|
setSortOrder(sortOrder?: string) {
|
||||||
if (sortOrder != null) {
|
if (sortOrder != null) {
|
||||||
this.sortOrder = sortOrder
|
this.#sortOrder = sortOrder
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setSortType(sortType?: string) {
|
setSortType(sortType?: string) {
|
||||||
if (sortType != null) {
|
if (sortType != null) {
|
||||||
this.sortType = sortType
|
this.#sortType = sortType
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setBookmark(bookmark?: string) {
|
setBookmark(bookmark?: string) {
|
||||||
if (bookmark != null) {
|
if (bookmark != null) {
|
||||||
this.bookmark = bookmark
|
this.#bookmark = bookmark
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -149,17 +149,17 @@ export class QueryBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
addString(key: string, partial: string) {
|
addString(key: string, partial: string) {
|
||||||
this.query.string![key] = partial
|
this.#query.string![key] = partial
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addFuzzy(key: string, fuzzy: string) {
|
addFuzzy(key: string, fuzzy: string) {
|
||||||
this.query.fuzzy![key] = fuzzy
|
this.#query.fuzzy![key] = fuzzy
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addRange(key: string, low: string | number, high: string | number) {
|
addRange(key: string, low: string | number, high: string | number) {
|
||||||
this.query.range![key] = {
|
this.#query.range![key] = {
|
||||||
low,
|
low,
|
||||||
high,
|
high,
|
||||||
}
|
}
|
||||||
|
@ -167,51 +167,51 @@ export class QueryBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
addEqual(key: string, value: any) {
|
addEqual(key: string, value: any) {
|
||||||
this.query.equal![key] = value
|
this.#query.equal![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addNotEqual(key: string, value: any) {
|
addNotEqual(key: string, value: any) {
|
||||||
this.query.notEqual![key] = value
|
this.#query.notEqual![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addEmpty(key: string, value: any) {
|
addEmpty(key: string, value: any) {
|
||||||
this.query.empty![key] = value
|
this.#query.empty![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addNotEmpty(key: string, value: any) {
|
addNotEmpty(key: string, value: any) {
|
||||||
this.query.notEmpty![key] = value
|
this.#query.notEmpty![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addOneOf(key: string, value: any) {
|
addOneOf(key: string, value: any) {
|
||||||
this.query.oneOf![key] = value
|
this.#query.oneOf![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addContains(key: string, value: any) {
|
addContains(key: string, value: any) {
|
||||||
this.query.contains![key] = value
|
this.#query.contains![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addNotContains(key: string, value: any) {
|
addNotContains(key: string, value: any) {
|
||||||
this.query.notContains![key] = value
|
this.#query.notContains![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addContainsAny(key: string, value: any) {
|
addContainsAny(key: string, value: any) {
|
||||||
this.query.containsAny![key] = value
|
this.#query.containsAny![key] = value
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
setAllOr() {
|
setAllOr() {
|
||||||
this.query.allOr = true
|
this.#query.allOr = true
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSpaces(input: string) {
|
handleSpaces(input: string) {
|
||||||
if (this.noEscaping) {
|
if (this.#noEscaping) {
|
||||||
return input
|
return input
|
||||||
} else {
|
} else {
|
||||||
return input.replace(/ /g, "_")
|
return input.replace(/ /g, "_")
|
||||||
|
@ -226,7 +226,7 @@ export class QueryBuilder<T> {
|
||||||
* @returns {string|*}
|
* @returns {string|*}
|
||||||
*/
|
*/
|
||||||
preprocess(value: any, { escape, lowercase, wrap, type }: any = {}) {
|
preprocess(value: any, { escape, lowercase, wrap, type }: any = {}) {
|
||||||
const hasVersion = !!this.version
|
const hasVersion = !!this.#version
|
||||||
// Determine if type needs wrapped
|
// Determine if type needs wrapped
|
||||||
const originalType = typeof value
|
const originalType = typeof value
|
||||||
// Convert to lowercase
|
// Convert to lowercase
|
||||||
|
@ -234,7 +234,7 @@ export class QueryBuilder<T> {
|
||||||
value = value.toLowerCase ? value.toLowerCase() : value
|
value = value.toLowerCase ? value.toLowerCase() : value
|
||||||
}
|
}
|
||||||
// Escape characters
|
// Escape characters
|
||||||
if (!this.noEscaping && escape && originalType === "string") {
|
if (!this.#noEscaping && escape && originalType === "string") {
|
||||||
value = `${value}`.replace(/[ #+\-&|!(){}\]^"~*?:\\]/g, "\\$&")
|
value = `${value}`.replace(/[ #+\-&|!(){}\]^"~*?:\\]/g, "\\$&")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ export class QueryBuilder<T> {
|
||||||
|
|
||||||
isMultiCondition() {
|
isMultiCondition() {
|
||||||
let count = 0
|
let count = 0
|
||||||
for (let filters of Object.values(this.query)) {
|
for (let filters of Object.values(this.#query)) {
|
||||||
// not contains is one massive filter in allOr mode
|
// not contains is one massive filter in allOr mode
|
||||||
if (typeof filters === "object") {
|
if (typeof filters === "object") {
|
||||||
count += Object.keys(filters).length
|
count += Object.keys(filters).length
|
||||||
|
@ -279,13 +279,13 @@ export class QueryBuilder<T> {
|
||||||
|
|
||||||
buildSearchQuery() {
|
buildSearchQuery() {
|
||||||
const builder = this
|
const builder = this
|
||||||
let allOr = this.query && this.query.allOr
|
let allOr = this.#query && this.#query.allOr
|
||||||
let query = allOr ? "" : "*:*"
|
let query = allOr ? "" : "*:*"
|
||||||
const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true }
|
const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true }
|
||||||
let tableId
|
let tableId
|
||||||
if (this.query.equal!.tableId) {
|
if (this.#query.equal!.tableId) {
|
||||||
tableId = this.query.equal!.tableId
|
tableId = this.#query.equal!.tableId
|
||||||
delete this.query.equal!.tableId
|
delete this.#query.equal!.tableId
|
||||||
}
|
}
|
||||||
|
|
||||||
const equal = (key: string, value: any) => {
|
const equal = (key: string, value: any) => {
|
||||||
|
@ -370,8 +370,8 @@ export class QueryBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the actual lucene search query string from JSON structure
|
// Construct the actual lucene search query string from JSON structure
|
||||||
if (this.query.string) {
|
if (this.#query.string) {
|
||||||
build(this.query.string, (key: string, value: any) => {
|
build(this.#query.string, (key: string, value: any) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -383,8 +383,8 @@ export class QueryBuilder<T> {
|
||||||
return `${key}:${value}*`
|
return `${key}:${value}*`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.query.range) {
|
if (this.#query.range) {
|
||||||
build(this.query.range, (key: string, value: any) => {
|
build(this.#query.range, (key: string, value: any) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -399,8 +399,8 @@ export class QueryBuilder<T> {
|
||||||
return `${key}:[${low} TO ${high}]`
|
return `${key}:[${low} TO ${high}]`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.query.fuzzy) {
|
if (this.#query.fuzzy) {
|
||||||
build(this.query.fuzzy, (key: string, value: any) => {
|
build(this.#query.fuzzy, (key: string, value: any) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -412,34 +412,34 @@ export class QueryBuilder<T> {
|
||||||
return `${key}:${value}~`
|
return `${key}:${value}~`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.query.equal) {
|
if (this.#query.equal) {
|
||||||
build(this.query.equal, equal)
|
build(this.#query.equal, equal)
|
||||||
}
|
}
|
||||||
if (this.query.notEqual) {
|
if (this.#query.notEqual) {
|
||||||
build(this.query.notEqual, (key: string, value: any) => {
|
build(this.#query.notEqual, (key: string, value: any) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}`
|
return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.query.empty) {
|
if (this.#query.empty) {
|
||||||
build(this.query.empty, (key: string) => `!${key}:["" TO *]`)
|
build(this.#query.empty, (key: string) => `!${key}:["" TO *]`)
|
||||||
}
|
}
|
||||||
if (this.query.notEmpty) {
|
if (this.#query.notEmpty) {
|
||||||
build(this.query.notEmpty, (key: string) => `${key}:["" TO *]`)
|
build(this.#query.notEmpty, (key: string) => `${key}:["" TO *]`)
|
||||||
}
|
}
|
||||||
if (this.query.oneOf) {
|
if (this.#query.oneOf) {
|
||||||
build(this.query.oneOf, oneOf)
|
build(this.#query.oneOf, oneOf)
|
||||||
}
|
}
|
||||||
if (this.query.contains) {
|
if (this.#query.contains) {
|
||||||
build(this.query.contains, contains)
|
build(this.#query.contains, contains)
|
||||||
}
|
}
|
||||||
if (this.query.notContains) {
|
if (this.#query.notContains) {
|
||||||
build(this.compressFilters(this.query.notContains), notContains)
|
build(this.compressFilters(this.#query.notContains), notContains)
|
||||||
}
|
}
|
||||||
if (this.query.containsAny) {
|
if (this.#query.containsAny) {
|
||||||
build(this.query.containsAny, containsAny)
|
build(this.#query.containsAny, containsAny)
|
||||||
}
|
}
|
||||||
// make sure table ID is always added as an AND
|
// make sure table ID is always added as an AND
|
||||||
if (tableId) {
|
if (tableId) {
|
||||||
|
@ -453,29 +453,31 @@ export class QueryBuilder<T> {
|
||||||
buildSearchBody() {
|
buildSearchBody() {
|
||||||
let body: any = {
|
let body: any = {
|
||||||
q: this.buildSearchQuery(),
|
q: this.buildSearchQuery(),
|
||||||
limit: Math.min(this.limit, 200),
|
limit: Math.min(this.#limit, 200),
|
||||||
include_docs: this.#includeDocs,
|
include_docs: this.#includeDocs,
|
||||||
}
|
}
|
||||||
if (this.bookmark) {
|
if (this.#bookmark) {
|
||||||
body.bookmark = this.bookmark
|
body.bookmark = this.#bookmark
|
||||||
}
|
}
|
||||||
if (this.sort) {
|
if (this.#sort) {
|
||||||
const order = this.sortOrder === "descending" ? "-" : ""
|
const order = this.#sortOrder === "descending" ? "-" : ""
|
||||||
const type = `<${this.sortType}>`
|
const type = `<${this.#sortType}>`
|
||||||
body.sort = `${order}${this.handleSpaces(this.sort)}${type}`
|
body.sort = `${order}${this.handleSpaces(this.#sort)}${type}`
|
||||||
}
|
}
|
||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
const { url, cookie } = getCouchInfo()
|
const { url, cookie } = getCouchInfo()
|
||||||
const fullPath = `${url}/${this.dbName}/_design/database/_search/${this.index}`
|
const fullPath = `${url}/${this.#dbName}/_design/database/_search/${
|
||||||
|
this.#index
|
||||||
|
}`
|
||||||
const body = this.buildSearchBody()
|
const body = this.buildSearchBody()
|
||||||
try {
|
try {
|
||||||
return await runQuery<T>(fullPath, body, cookie)
|
return await runQuery<T>(fullPath, body, cookie)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.status === 404 && this.indexBuilder) {
|
if (err.status === 404 && this.#indexBuilder) {
|
||||||
await this.indexBuilder()
|
await this.#indexBuilder()
|
||||||
return await runQuery<T>(fullPath, body, cookie)
|
return await runQuery<T>(fullPath, body, cookie)
|
||||||
} else {
|
} else {
|
||||||
throw err
|
throw err
|
||||||
|
|
Loading…
Reference in New Issue