@lbu/store
Advanced tools
Comparing version 0.0.82 to 0.0.83
115
index.d.ts
import * as minioVendor from "minio"; | ||
import * as postgresVendor from "postgres"; | ||
import { queries } from "./src/generated/index.js"; | ||
@@ -217,2 +218,69 @@ /** | ||
export interface FileGroup { | ||
id: string; | ||
name?: string; | ||
order: number; | ||
meta: {}; | ||
file?: string; | ||
parent?: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
deletedAt: Date; | ||
} | ||
export interface NestedFileGroup { | ||
id: string; | ||
name?: string; | ||
order: number; | ||
meta: {}; | ||
parent?: string; | ||
isDirectory: boolean; | ||
file?: | ||
| { | ||
id: string; | ||
bucketName?: string; | ||
contentLength?: number; | ||
contentType?: string; | ||
name?: string; | ||
createdAt?: string; | ||
updatedAt?: string; | ||
} | ||
| undefined | ||
| string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
deletedAt: Date; | ||
children?: NestedFileGroup[]; | ||
} | ||
/** | ||
* Assigns children of the provided fileGroup to the parent. | ||
* Returns the affected children. | ||
*/ | ||
export function hoistChildrenToParent( | ||
sql: Postgres, | ||
fileGroup: FileGroup, | ||
): Promise<FileGroup[]>; | ||
/** | ||
* Update the order of the provided id's in relation to each other. | ||
* This function does not check if all files are in the same group. | ||
*/ | ||
export function updateFileGroupOrder( | ||
sql: Postgres, | ||
ids: string[], | ||
): Promise<void>; | ||
/** | ||
* Return a result with nested file groups and files, sorted completely by the order id. | ||
*/ | ||
export function getNestedFileGroups( | ||
sql: Postgres, | ||
where?: { | ||
deletedAtIncludeNotNull?: boolean; | ||
rootId?: string; | ||
excludeFiles?: boolean; | ||
}, | ||
): Promise<NestedFileGroup[]>; | ||
export interface FileCacheOptions { | ||
@@ -419,1 +487,48 @@ /** | ||
export const storeStructure: any; | ||
/** | ||
* Build safe, parameterized queries. | ||
*/ | ||
export interface QueryPart { | ||
strings: string[]; | ||
values: any[]; | ||
append(part: QueryPart): QueryPart; | ||
exec(sql: Postgres): postgresVendor.PendingQuery<any>; | ||
} | ||
/** | ||
* Format and append query parts, and exec the final result in a safe way. | ||
* Undefined values are skipped, as they are not allowed in queries. | ||
* The provided values may contain other 'query``' calls, and they will be inserted | ||
* appropriately. | ||
* | ||
* @example | ||
* ``` | ||
* const getWhere = (value) => query`WHERE foo = ${value}`; | ||
* const selectResult = await query`SELECT * FROM "myTable" ${getWhere(5)}`.exec(sql); | ||
* // sql: SELECT * FROM "myTable" WHERE foo = $1 | ||
* // arguments: [ 5 ] | ||
* ``` | ||
*/ | ||
export function query(strings: string[], ...values: any[]): QueryPart; | ||
/** | ||
* Creates a transaction, executes the query, and rollback the transaction afterwards. | ||
* This is safe to use with insert, update and delete queries. | ||
* | ||
* By default returns text, but can also return json. | ||
* Note that explain output is highly depended on the current data and usage of the tables. | ||
*/ | ||
export function explainAnalyzeQuery( | ||
sql: Postgres, | ||
queryPart: QueryPart, | ||
options?: { jsonResult?: true }, | ||
): Promise<string | any>; | ||
/** | ||
* Overwrite used generated queries. | ||
* This is needed when you want cascading soft deletes to any of the exposed types | ||
*/ | ||
export function setStoreQueries(q: typeof queries): void; |
11
index.js
@@ -35,2 +35,8 @@ import { dirnameForModule } from "@lbu/stdlib"; | ||
export { | ||
hoistChildrenToParent, | ||
updateFileGroupOrder, | ||
getNestedFileGroups, | ||
} from "./src/file-group.js"; | ||
export { FileCache } from "./src/file-cache.js"; | ||
@@ -47,2 +53,5 @@ | ||
export const migrations = `${dirnameForModule(import.meta)}/migrations`; | ||
export { structure as storeStructure } from "./src/generated/structure.js"; | ||
export { structure as storeStructure } from "./src/generated/index.js"; | ||
export { query, explainAnalyzeQuery } from "./src/query.js"; | ||
export { setStoreQueries } from "./src/generated.js"; |
{ | ||
"name": "@lbu/store", | ||
"version": "0.0.82", | ||
"version": "0.0.83", | ||
"description": "Postgres & S3-compatible wrappers for common things", | ||
@@ -18,4 +18,4 @@ "main": "./index.js", | ||
"dependencies": { | ||
"@lbu/insight": "0.0.82", | ||
"@lbu/stdlib": "0.0.82", | ||
"@lbu/insight": "0.0.83", | ||
"@lbu/stdlib": "0.0.83", | ||
"@types/minio": "7.0.6", | ||
@@ -47,3 +47,3 @@ "mime-types": "2.1.27", | ||
}, | ||
"gitHead": "33cf141dc201f1df7a95c4f4fc7328f304502a94" | ||
"gitHead": "aaf78ed69ee3b5b03be57f9acf4669c7134ae308" | ||
} |
import { createReadStream } from "fs"; | ||
import { uuid } from "@lbu/stdlib"; | ||
import mime from "mime-types"; | ||
import { storeQueries } from "./generated/queries.js"; | ||
import { queries } from "./generated.js"; | ||
import { listObjects } from "./minio.js"; | ||
const queries = { | ||
const fileQueries = { | ||
copyFile: (sql, targetId, targetBucket, sourceId, sourceBucket) => sql` | ||
@@ -51,3 +51,3 @@ INSERT INTO "file" ("id", "bucketName", "contentType", "contentLength", "name", "meta") | ||
props.contentLength = 0; | ||
const [intermediate] = await storeQueries.fileInsert(sql, props); | ||
const [intermediate] = await queries.fileInsert(sql, props); | ||
props.id = intermediate.id; | ||
@@ -66,3 +66,3 @@ } | ||
const [result] = await storeQueries.fileUpdate(sql, props, { | ||
const [result] = await queries.fileUpdate(sql, props, { | ||
id: props.id, | ||
@@ -112,3 +112,3 @@ }); | ||
) { | ||
const [intermediate] = await queries.copyFile( | ||
const [intermediate] = await fileQueries.copyFile( | ||
sql, | ||
@@ -123,3 +123,3 @@ uuid(), | ||
const [result] = await storeQueries.fileSelect(sql, { | ||
const [result] = await queries.fileSelect(sql, { | ||
id: intermediate.id, | ||
@@ -138,5 +138,5 @@ }); | ||
const minioObjectsPromise = listObjects(minio, bucketName); | ||
const knownIds = await storeQueries.fileSelect(sql, { | ||
const knownIds = await queries.fileSelect(sql, { | ||
bucketName: bucketName, | ||
deletedAtInclude: true, | ||
deletedAtIncludeNotNull: true, | ||
}); | ||
@@ -143,0 +143,0 @@ |
@@ -1,3 +0,7 @@ | ||
export const structureString = | ||
'{"store":{"jobInterval":{"type":"object","docString":"","isOptional":false,"uniqueName":"StoreJobInterval","group":"store","name":"jobInterval","validator":{"strict":true},"keys":{"years":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}},"months":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}},"days":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}},"hours":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}},"minutes":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}},"seconds":{"type":"number","docString":"","isOptional":true,"validator":{"convert":false,"floatingPoint":false}}},"enableQueries":false},"file":{"type":"object","docString":"","isOptional":false,"uniqueName":"StoreFile","group":"store","name":"file","validator":{"strict":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"sql":{"primary":true,"searchable":true}},"bucketName":{"type":"string","docString":"","isOptional":false,"sql":{"primary":false,"searchable":true},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false,"min":1}},"contentLength":{"type":"number","docString":"","isOptional":false,"validator":{"convert":false,"floatingPoint":false}},"contentType":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false,"min":1}},"name":{"type":"string","docString":"","isOptional":false,"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false,"min":1}},"meta":{"type":"reference","docString":"","isOptional":false,"reference":{"uniqueName":"StoreFileMeta","group":"store","name":"fileMeta"}}},"enableQueries":true,"queryOptions":{"withSoftDeletes":true,"withDates":false}},"session":{"type":"object","docString":"","isOptional":false,"uniqueName":"StoreSession","group":"store","name":"session","validator":{"strict":true},"keys":{"id":{"type":"uuid","docString":"","isOptional":false,"sql":{"primary":true,"searchable":true}},"expires":{"type":"date","docString":"","isOptional":false,"sql":{"primary":false,"searchable":true}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}"}},"enableQueries":true,"queryOptions":{"withSoftDeletes":false,"withDates":true}},"job":{"type":"object","docString":"","isOptional":false,"uniqueName":"StoreJob","group":"store","name":"job","validator":{"strict":true},"keys":{"id":{"type":"number","docString":"","isOptional":false,"sql":{"primary":true,"searchable":true},"validator":{"convert":false,"floatingPoint":false}},"isComplete":{"type":"boolean","docString":"","isOptional":true,"defaultValue":"false","sql":{"primary":false,"searchable":true},"validator":{"convert":false}},"priority":{"type":"number","docString":"","isOptional":true,"defaultValue":"0","validator":{"convert":false,"floatingPoint":false}},"scheduledAt":{"type":"date","docString":"","isOptional":true,"defaultValue":"(new Date())","sql":{"primary":false,"searchable":true}},"name":{"type":"string","docString":"","isOptional":false,"sql":{"primary":false,"searchable":true},"validator":{"convert":false,"trim":false,"lowerCase":false,"upperCase":false,"min":1}},"data":{"type":"any","docString":"","isOptional":true,"defaultValue":"{}"}},"enableQueries":true,"queryOptions":{"withSoftDeletes":false,"withDates":true}},"fileMeta":{"type":"object","docString":"User definable, optional object to store whatever you want","isOptional":true,"defaultValue":"{}","uniqueName":"StoreFileMeta","group":"store","name":"fileMeta","validator":{"strict":true},"keys":{},"enableQueries":false}}}'; | ||
export const structure = JSON.parse(structureString); | ||
// Generated by @lbu/code-gen | ||
/* eslint-disable no-unused-vars */ | ||
import { storeStructure } from "./store/structure.js"; | ||
export const structure = Object.assign({}, storeStructure); | ||
export const structureString = JSON.stringify(structure); |
// Generated by @lbu/code-gen | ||
/* eslint-disable no-unused-vars */ | ||
// An export soo all things work correctly with linters, ts, ... | ||
export const __generated__ = true; | ||
/** | ||
* @name StoreFile | ||
* | ||
* @typedef { { "id":string, "bucketName":string, "contentLength":number, "contentType":string, "name":string, "meta":StoreFileMeta, "createdAt":Date, "updatedAt":Date, "deletedAt"?:Date, }} | ||
* @typedef {{"bucketName": string, "contentLength": number, "contentType": string, "name": string, "meta": StoreFileMeta, "id": string, "createdAt": Date, "updatedAt": Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreFile_Input | ||
* | ||
* @typedef { { "id":string, "bucketName":string, "contentLength":number, "contentType":string, "name":string, "meta":StoreFileMeta_Input, "createdAt"?:string, "updatedAt"?:string, "deletedAt"?:string, }} | ||
* @name StoreFileGroup | ||
* @typedef {{"name"?: string, "order": number, "meta": StoreFileGroupMeta, "id": string, "file"?: string, "parent"?: string, "createdAt": Date, "updatedAt": Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreFileInsertPartial | ||
* | ||
* @typedef { { "bucketName":string, "contentLength":number, "contentType":string, "name":string, "meta":StoreFileMeta, "createdAt":Date, "updatedAt":Date, "deletedAt"?:Date, }} | ||
* @name StoreFileGroupMeta | ||
* @typedef {{}} | ||
*/ | ||
/** | ||
* @name StoreFileInsertPartial_Input | ||
* | ||
* @typedef { { "bucketName":string, "contentLength":number, "contentType":string, "name":string, "meta":StoreFileMeta_Input, "createdAt"?:string, "updatedAt"?:string, "deletedAt"?:string, }} | ||
* @name StoreFileGroupView | ||
* @typedef {{"name"?: string, "order": number, "meta": StoreFileGroupMeta, "isDirectory": boolean, "id": string, "file"?: string, "parent"?: string, "createdAt": Date, "updatedAt": Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreFileMeta | ||
* Docs: User definable, optional object to store whatever you want | ||
* @typedef { { }} | ||
* @typedef {{}} | ||
*/ | ||
/** | ||
* @name StoreFileMeta_Input | ||
* Docs: User definable, optional object to store whatever you want | ||
* @typedef { { } |undefined} | ||
* @name StoreJob | ||
* @typedef {{"id": number, "isComplete": boolean, "priority": number, "scheduledAt": Date, "name": string, "data": *, "createdAt": Date, "updatedAt": Date, }} | ||
*/ | ||
/** | ||
* @name StoreFileWhere | ||
* Docs: By default 'where.deletedAtInclude' will only include 'null' values. To use the other generated variants like 'deletedAtGreaterThan', set this value to 'true'. | ||
* @typedef { { "id"?:string, "idIn"?:(string)[] , "bucketName"?:string , "bucketNameLike"?:string , "createdAt"?:Date, "createdAtGreaterThan"?:Date, "createdAtLowerThan"?:Date, "updatedAt"?:Date, "updatedAtGreaterThan"?:Date, "updatedAtLowerThan"?:Date, "deletedAtInclude"?:, "deletedAt"?:Date, "deletedAtGreaterThan"?:Date, "deletedAtLowerThan"?:Date, }} | ||
* @name StoreJobInterval | ||
* @typedef {{"years"?: number, "months"?: number, "days"?: number, "hours"?: number, "minutes"?: number, "seconds"?: number, }} | ||
*/ | ||
/** | ||
* @name StoreFileWhere_Input | ||
* Docs: By default 'where.deletedAtInclude' will only include 'null' values. To use the other generated variants like 'deletedAtGreaterThan', set this value to 'true'. | ||
* @typedef { { "id"?:string, "idIn"?:(string)[] , "bucketName"?:string , "bucketNameLike"?:string , "createdAt"?:string, "createdAtGreaterThan"?:string, "createdAtLowerThan"?:string, "updatedAt"?:string, "updatedAtGreaterThan"?:string, "updatedAtLowerThan"?:string, "deletedAtInclude"?:, "deletedAt"?:string, "deletedAtGreaterThan"?:string, "deletedAtLowerThan"?:string, }} | ||
* @name StoreSession | ||
* @typedef {{"expires": Date, "data": *, "id": string, "createdAt": Date, "updatedAt": Date, }} | ||
*/ | ||
/** | ||
* @name StoreJob | ||
* | ||
* @typedef { { "id":number, "isComplete":boolean, "priority":number, "scheduledAt":Date, "name":string, "data":*, "createdAt":Date, "updatedAt":Date, }} | ||
* @name StoreFileWhere | ||
* @typedef {{"id"?: string, "idNotEqual"?: string, "idIn"?: (string)[], "idNotIn"?: (string)[], "idLike"?: string, "idNotLike"?: string, "bucketName"?: string, "bucketNameNotEqual"?: string, "bucketNameIn"?: (string)[], "bucketNameNotIn"?: (string)[], "bucketNameLike"?: string, "bucketNameNotLike"?: string, "createdAt"?: Date, "createdAtNotEqual"?: Date, "createdAtIn"?: (Date)[], "createdAtNotIn"?: (Date)[], "createdAtGreaterThan"?: Date, "createdAtLowerThan"?: Date, "createdAtIsNull"?: boolean, "createdAtIsNotNull"?: boolean, "updatedAt"?: Date, "updatedAtNotEqual"?: Date, "updatedAtIn"?: (Date)[], "updatedAtNotIn"?: (Date)[], "updatedAtGreaterThan"?: Date, "updatedAtLowerThan"?: Date, "updatedAtIsNull"?: boolean, "updatedAtIsNotNull"?: boolean, "deletedAt"?: Date, "deletedAtNotEqual"?: Date, "deletedAtIn"?: (Date)[], "deletedAtNotIn"?: (Date)[], "deletedAtGreaterThan"?: Date, "deletedAtLowerThan"?: Date, "deletedAtIncludeNotNull"?: boolean, }} | ||
*/ | ||
/** | ||
* @name StoreJob_Input | ||
* | ||
* @typedef { { "id":number, "isComplete"?:boolean , "priority"?:number , "scheduledAt"?:string, "name":string, "data"?:* , "createdAt"?:string, "updatedAt"?:string, }} | ||
* @name StoreFileGroupWhere | ||
* @typedef {{"id"?: string, "idNotEqual"?: string, "idIn"?: (string)[], "idNotIn"?: (string)[], "idLike"?: string, "idNotLike"?: string, "file"?: string, "fileNotEqual"?: string, "fileIn"?: (string)[], "fileNotIn"?: (string)[], "fileLike"?: string, "fileNotLike"?: string, "fileIsNull"?: boolean, "fileIsNotNull"?: boolean, "parent"?: string, "parentNotEqual"?: string, "parentIn"?: (string)[], "parentNotIn"?: (string)[], "parentLike"?: string, "parentNotLike"?: string, "parentIsNull"?: boolean, "parentIsNotNull"?: boolean, "createdAt"?: Date, "createdAtNotEqual"?: Date, "createdAtIn"?: (Date)[], "createdAtNotIn"?: (Date)[], "createdAtGreaterThan"?: Date, "createdAtLowerThan"?: Date, "createdAtIsNull"?: boolean, "createdAtIsNotNull"?: boolean, "updatedAt"?: Date, "updatedAtNotEqual"?: Date, "updatedAtIn"?: (Date)[], "updatedAtNotIn"?: (Date)[], "updatedAtGreaterThan"?: Date, "updatedAtLowerThan"?: Date, "updatedAtIsNull"?: boolean, "updatedAtIsNotNull"?: boolean, "deletedAt"?: Date, "deletedAtNotEqual"?: Date, "deletedAtIn"?: (Date)[], "deletedAtNotIn"?: (Date)[], "deletedAtGreaterThan"?: Date, "deletedAtLowerThan"?: Date, "deletedAtIncludeNotNull"?: boolean, }} | ||
*/ | ||
/** | ||
* @name StoreJobInsertPartial | ||
* | ||
* @typedef { { "isComplete":boolean, "priority":number, "scheduledAt":Date, "name":string, "data":*, "createdAt":Date, "updatedAt":Date, }} | ||
* @name StoreFileGroupViewWhere | ||
* @typedef {{"id"?: string, "idNotEqual"?: string, "idIn"?: (string)[], "idNotIn"?: (string)[], "idLike"?: string, "idNotLike"?: string, "isDirectory"?: boolean, "file"?: string, "fileNotEqual"?: string, "fileIn"?: (string)[], "fileNotIn"?: (string)[], "fileLike"?: string, "fileNotLike"?: string, "fileIsNull"?: boolean, "fileIsNotNull"?: boolean, "parent"?: string, "parentNotEqual"?: string, "parentIn"?: (string)[], "parentNotIn"?: (string)[], "parentLike"?: string, "parentNotLike"?: string, "parentIsNull"?: boolean, "parentIsNotNull"?: boolean, "createdAt"?: Date, "createdAtNotEqual"?: Date, "createdAtIn"?: (Date)[], "createdAtNotIn"?: (Date)[], "createdAtGreaterThan"?: Date, "createdAtLowerThan"?: Date, "createdAtIsNull"?: boolean, "createdAtIsNotNull"?: boolean, "updatedAt"?: Date, "updatedAtNotEqual"?: Date, "updatedAtIn"?: (Date)[], "updatedAtNotIn"?: (Date)[], "updatedAtGreaterThan"?: Date, "updatedAtLowerThan"?: Date, "updatedAtIsNull"?: boolean, "updatedAtIsNotNull"?: boolean, "deletedAt"?: Date, "deletedAtNotEqual"?: Date, "deletedAtIn"?: (Date)[], "deletedAtNotIn"?: (Date)[], "deletedAtGreaterThan"?: Date, "deletedAtLowerThan"?: Date, "deletedAtIncludeNotNull"?: boolean, }} | ||
*/ | ||
/** | ||
* @name StoreJobInsertPartial_Input | ||
* | ||
* @typedef { { "isComplete"?:boolean , "priority"?:number , "scheduledAt"?:string, "name":string, "data"?:* , "createdAt"?:string, "updatedAt"?:string, }} | ||
* @name StoreJobWhere | ||
* @typedef {{"id"?: number, "idNotEqual"?: number, "idIn"?: (number)[], "idNotIn"?: (number)[], "idGreaterThan"?: number, "idLowerThan"?: number, "isComplete"?: boolean, "isCompleteIsNull"?: boolean, "isCompleteIsNotNull"?: boolean, "name"?: string, "nameNotEqual"?: string, "nameIn"?: (string)[], "nameNotIn"?: (string)[], "nameLike"?: string, "nameNotLike"?: string, "scheduledAt"?: Date, "scheduledAtNotEqual"?: Date, "scheduledAtIn"?: (Date)[], "scheduledAtNotIn"?: (Date)[], "scheduledAtGreaterThan"?: Date, "scheduledAtLowerThan"?: Date, "scheduledAtIsNull"?: boolean, "scheduledAtIsNotNull"?: boolean, "createdAt"?: Date, "createdAtNotEqual"?: Date, "createdAtIn"?: (Date)[], "createdAtNotIn"?: (Date)[], "createdAtGreaterThan"?: Date, "createdAtLowerThan"?: Date, "createdAtIsNull"?: boolean, "createdAtIsNotNull"?: boolean, "updatedAt"?: Date, "updatedAtNotEqual"?: Date, "updatedAtIn"?: (Date)[], "updatedAtNotIn"?: (Date)[], "updatedAtGreaterThan"?: Date, "updatedAtLowerThan"?: Date, "updatedAtIsNull"?: boolean, "updatedAtIsNotNull"?: boolean, }} | ||
*/ | ||
/** | ||
* @name StoreJobInterval | ||
* | ||
* @typedef { { "years"?:number , "months"?:number , "days"?:number , "hours"?:number , "minutes"?:number , "seconds"?:number , }} | ||
* @name StoreSessionWhere | ||
* @typedef {{"id"?: string, "idNotEqual"?: string, "idIn"?: (string)[], "idNotIn"?: (string)[], "idLike"?: string, "idNotLike"?: string, "expires"?: Date, "expiresNotEqual"?: Date, "expiresIn"?: (Date)[], "expiresNotIn"?: (Date)[], "expiresGreaterThan"?: Date, "expiresLowerThan"?: Date, "createdAt"?: Date, "createdAtNotEqual"?: Date, "createdAtIn"?: (Date)[], "createdAtNotIn"?: (Date)[], "createdAtGreaterThan"?: Date, "createdAtLowerThan"?: Date, "createdAtIsNull"?: boolean, "createdAtIsNotNull"?: boolean, "updatedAt"?: Date, "updatedAtNotEqual"?: Date, "updatedAtIn"?: (Date)[], "updatedAtNotIn"?: (Date)[], "updatedAtGreaterThan"?: Date, "updatedAtLowerThan"?: Date, "updatedAtIsNull"?: boolean, "updatedAtIsNotNull"?: boolean, }} | ||
*/ | ||
/** | ||
* @name StoreJobInterval_Input | ||
* | ||
* @typedef { StoreJobInterval} | ||
* @name StoreFileInsertPartial | ||
* @typedef {{"id"?: string, "contentLength": number, "bucketName": string, "contentType": string, "name": string, "meta"?: {}, "createdAt"?: Date, "updatedAt"?: Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreJobWhere | ||
* | ||
* @typedef { { "id"?:number , "idGreaterThan"?:number , "idLowerThan"?:number , "isComplete"?:boolean , "scheduledAt"?:Date, "scheduledAtGreaterThan"?:Date, "scheduledAtLowerThan"?:Date, "name"?:string , "nameLike"?:string , "createdAt"?:Date, "createdAtGreaterThan"?:Date, "createdAtLowerThan"?:Date, "updatedAt"?:Date, "updatedAtGreaterThan"?:Date, "updatedAtLowerThan"?:Date, }} | ||
* @name StoreFileUpdatePartial | ||
* @typedef {{"contentLength"?: number, "bucketName"?: string, "contentType"?: string, "name"?: string, "meta"?: {}, "createdAt"?: Date, "updatedAt"?: Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreJobWhere_Input | ||
* | ||
* @typedef { { "id"?:number , "idGreaterThan"?:number , "idLowerThan"?:number , "isComplete"?:boolean , "scheduledAt"?:string, "scheduledAtGreaterThan"?:string, "scheduledAtLowerThan"?:string, "name"?:string , "nameLike"?:string , "createdAt"?:string, "createdAtGreaterThan"?:string, "createdAtLowerThan"?:string, "updatedAt"?:string, "updatedAtGreaterThan"?:string, "updatedAtLowerThan"?:string, }} | ||
* @name StoreFileGroupInsertPartial | ||
* @typedef {{"id"?: string, "order"?: number, "file"?: string, "parent"?: string, "name"?: string, "meta"?: {}, "createdAt"?: Date, "updatedAt"?: Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSession | ||
* | ||
* @typedef { { "id":string, "expires":Date, "data":*, "createdAt":Date, "updatedAt":Date, }} | ||
* @name StoreFileGroupUpdatePartial | ||
* @typedef {{"order"?: number, "file"?: string, "parent"?: string, "name"?: string, "meta"?: {}, "createdAt"?: Date, "updatedAt"?: Date, "deletedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSession_Input | ||
* | ||
* @typedef { { "id":string, "expires":string, "data"?:* , "createdAt"?:string, "updatedAt"?:string, }} | ||
* @name StoreJobInsertPartial | ||
* @typedef {{"id"?: number, "isComplete"?: boolean, "priority"?: number, "name": string, "scheduledAt"?: Date, "data"?: *, "createdAt"?: Date, "updatedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSessionInsertPartial | ||
* | ||
* @typedef { { "expires":Date, "data":*, "createdAt":Date, "updatedAt":Date, }} | ||
* @name StoreJobUpdatePartial | ||
* @typedef {{"isComplete"?: boolean, "priority"?: number, "name"?: string, "scheduledAt"?: Date, "data"?: *, "createdAt"?: Date, "updatedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSessionInsertPartial_Input | ||
* | ||
* @typedef { { "expires":string, "data"?:* , "createdAt"?:string, "updatedAt"?:string, }} | ||
* @name StoreSessionInsertPartial | ||
* @typedef {{"id"?: string, "expires": Date, "data"?: *, "createdAt"?: Date, "updatedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSessionWhere | ||
* | ||
* @typedef { { "id"?:string, "idIn"?:(string)[] , "expires"?:Date, "expiresGreaterThan"?:Date, "expiresLowerThan"?:Date, "createdAt"?:Date, "createdAtGreaterThan"?:Date, "createdAtLowerThan"?:Date, "updatedAt"?:Date, "updatedAtGreaterThan"?:Date, "updatedAtLowerThan"?:Date, }} | ||
* @name StoreSessionUpdatePartial | ||
* @typedef {{"expires"?: Date, "data"?: *, "createdAt"?: Date, "updatedAt"?: Date, }} | ||
*/ | ||
/** | ||
* @name StoreSessionWhere_Input | ||
* | ||
* @typedef { { "id"?:string, "idIn"?:(string)[] , "expires"?:string, "expiresGreaterThan"?:string, "expiresLowerThan"?:string, "createdAt"?:string, "createdAtGreaterThan"?:string, "createdAtLowerThan"?:string, "updatedAt"?:string, "updatedAtGreaterThan"?:string, "updatedAtLowerThan"?:string, }} | ||
*/ |
@@ -5,10 +5,2 @@ import { isProduction, merge } from "@lbu/stdlib"; | ||
/** | ||
* @name Postgres | ||
* | ||
* See https://github.com/porsager/postgres for docs | ||
* | ||
* @typedef {*} | ||
*/ | ||
/** | ||
* @param {object} [opts] | ||
@@ -15,0 +7,0 @@ * @param {boolean} [opts.createIfNotExists] |
import { log } from "@lbu/insight"; | ||
import { storeQueries } from "./generated/queries.js"; | ||
import { queries } from "./generated.js"; | ||
const LBU_RECURRING_JOB = "lbu.job.recurring"; | ||
const queries = { | ||
const queueQueries = { | ||
// Should only run in a transaction | ||
@@ -100,3 +100,3 @@ getAnyJob: (sql) => sql` | ||
// Default query ignores name | ||
this.newJobQuery = queries.getAnyJob.bind(undefined); | ||
this.newJobQuery = queueQueries.getAnyJob.bind(undefined); | ||
@@ -106,3 +106,6 @@ if (typeof nameOrOptions === "string") { | ||
// when executing the query | ||
this.newJobQuery = queries.getJobByName.bind(undefined, nameOrOptions); | ||
this.newJobQuery = queueQueries.getJobByName.bind( | ||
undefined, | ||
nameOrOptions, | ||
); | ||
this.name = nameOrOptions; | ||
@@ -235,3 +238,3 @@ } else { | ||
const [jobData] = await storeQueries.jobSelect(sql, { | ||
const [jobData] = await queries.jobSelect(sql, { | ||
id: job.id, | ||
@@ -278,3 +281,3 @@ }); | ||
export async function addJobToQueue(sql, job) { | ||
const [result] = await storeQueries.jobInsert(sql, { | ||
const [result] = await queries.jobInsert(sql, { | ||
...job, | ||
@@ -302,3 +305,3 @@ name: job.name ?? process.env.APP_NAME, | ||
const existingJobs = await queries.getRecurringJobForName(sql, name); | ||
const existingJobs = await queueQueries.getRecurringJobForName(sql, name); | ||
@@ -326,3 +329,3 @@ if (existingJobs.length > 0) { | ||
async function getPendingQueueSize(sql) { | ||
const [result] = await queries.getPendingQueueSize(sql); | ||
const [result] = await queueQueries.getPendingQueueSize(sql); | ||
@@ -344,3 +347,3 @@ // sql returns 'null' if no rows match, so coalesce in to '0' | ||
async function getPendingQueueSizeForName(sql, name) { | ||
const [result] = await queries.getPendingQueueSizeForName(sql, name); | ||
const [result] = await queueQueries.getPendingQueueSizeForName(sql, name); | ||
@@ -364,3 +367,7 @@ // sql returns 'null' if no rows match, so coalesce in to '0' | ||
async function getAverageTimeToJobCompletion(sql, startDate, endDate) { | ||
const [result] = await queries.getAverageJobTime(sql, startDate, endDate); | ||
const [result] = await queueQueries.getAverageJobTime( | ||
sql, | ||
startDate, | ||
endDate, | ||
); | ||
@@ -386,3 +393,3 @@ return parseFloat(result?.completionTime ?? 0); | ||
) { | ||
const [result] = await queries.getAverageJobTimeForName( | ||
const [result] = await queueQueries.getAverageJobTimeForName( | ||
sql, | ||
@@ -389,0 +396,0 @@ name, |
@@ -1,5 +0,34 @@ | ||
import { storeQueries } from "./generated/queries.js"; | ||
import { queries } from "./generated.js"; | ||
import { | ||
sessionFields, | ||
sessionInsertValues, | ||
sessionUpdateSet, | ||
} from "./generated/index.js"; | ||
import { query } from "./query.js"; | ||
const EIGHTEEN_HOURS = 18 * 60 * 60 * 1000; | ||
const sessionQueries = { | ||
/** | ||
* Upsert a query by id. | ||
* We can't reuse `sessionInsertValues` here since that won't account for the 'id' field | ||
* | ||
* @param {Postgres} sql | ||
* @param {StoreSessionInsertPartial & { id?: string }} value | ||
* @returns {postgres.PendingQuery<any>} | ||
*/ | ||
upsertById: (sql, value) => | ||
query` | ||
INSERT INTO "session" (${sessionFields("")}) | ||
VALUES | ||
${sessionInsertValues(value, { includePrimaryKey: true })} | ||
ON CONFLICT ("id") | ||
DO UPDATE SET ${sessionUpdateSet({ | ||
expires: value.expires, | ||
data: value.data, | ||
})} | ||
RETURNING ${sessionFields("")} | ||
`.exec(sql), | ||
}; | ||
/** | ||
@@ -12,3 +41,3 @@ * @param {Postgres} sql | ||
get: async (sid) => { | ||
const [data] = await storeQueries.sessionSelect(sql, { | ||
const [data] = await queries.sessionSelect(sql, { | ||
id: sid, | ||
@@ -20,3 +49,4 @@ expiresGreaterThan: new Date(), | ||
} | ||
return JSON.parse(data.data); | ||
return data.data; | ||
}, | ||
@@ -34,13 +64,13 @@ set: async (sid, sess, maxAge) => { | ||
await storeQueries.sessionUpsert(sql, { | ||
await sessionQueries.upsertById(sql, { | ||
id: sid, | ||
expires, | ||
data: JSON.stringify(sess), | ||
data: sess, | ||
}); | ||
}, | ||
destroy: async (sid) => { | ||
await storeQueries.sessionDelete(sql, { id: sid }); | ||
await queries.sessionDelete(sql, { id: sid }); | ||
}, | ||
clean: () => { | ||
return storeQueries.sessionDelete(sql, { | ||
return queries.sessionDelete(sql, { | ||
expiresLowerThan: new Date(), | ||
@@ -47,0 +77,0 @@ }); |
@@ -71,5 +71,8 @@ import { log } from "@lbu/insight"; | ||
await creationSql` | ||
SELECT pg_terminate_backend(pg_stat_activity.pid) | ||
FROM pg_stat_activity | ||
WHERE pg_stat_activity.datname = ${process.env.APP_NAME} | ||
SELECT | ||
pg_terminate_backend(pg_stat_activity.pid) | ||
FROM | ||
pg_stat_activity | ||
WHERE | ||
pg_stat_activity.datname = ${process.env.APP_NAME} | ||
AND pid <> pg_backend_pid() | ||
@@ -92,6 +95,10 @@ `; | ||
const tables = await sql` | ||
SELECT table_name | ||
FROM information_schema.tables | ||
WHERE table_schema = 'public' | ||
SELECT | ||
table_name | ||
FROM | ||
information_schema.tables | ||
WHERE | ||
table_schema = 'public' | ||
AND table_name != 'migration' | ||
AND table_type = 'BASE TABLE' | ||
`; | ||
@@ -98,0 +105,0 @@ if (tables.length > 0) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
157868
30
4695
1
+ Added@lbu/insight@0.0.83(transitive)
+ Added@lbu/stdlib@0.0.83(transitive)
+ Added@types/node@14.11.10(transitive)
- Removed@lbu/insight@0.0.82(transitive)
- Removed@lbu/stdlib@0.0.82(transitive)
- Removed@types/node@14.11.8(transitive)
Updated@lbu/insight@0.0.83
Updated@lbu/stdlib@0.0.83