@harperfast/harper 5.0.0-alpha.10 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/BinObjects.js +17 -0
- package/bin/cliOperations.js +157 -0
- package/bin/copyDb.ts +280 -0
- package/bin/harper.js +156 -0
- package/bin/install.js +15 -0
- package/bin/lite.js +5 -0
- package/bin/restart.js +201 -0
- package/bin/run.js +409 -0
- package/bin/status.js +65 -0
- package/bin/stop.js +22 -0
- package/bin/upgrade.js +134 -0
- package/components/Application.ts +646 -0
- package/components/ApplicationScope.ts +49 -0
- package/components/Component.ts +53 -0
- package/components/ComponentV1.ts +342 -0
- package/components/DEFAULT_CONFIG.ts +18 -0
- package/components/EntryHandler.ts +227 -0
- package/components/Logger.ts +14 -0
- package/components/OptionsWatcher.ts +354 -0
- package/components/PluginModule.ts +6 -0
- package/components/Scope.ts +329 -0
- package/components/componentLoader.ts +529 -0
- package/components/deriveCommonPatternBase.ts +31 -0
- package/components/deriveGlobOptions.ts +44 -0
- package/components/deriveURLPath.ts +57 -0
- package/components/operations.js +658 -0
- package/components/operationsValidation.js +246 -0
- package/components/packageComponent.ts +39 -0
- package/components/requestRestart.ts +26 -0
- package/components/resolveBaseURLPath.ts +38 -0
- package/components/status/ComponentStatus.ts +110 -0
- package/components/status/ComponentStatusRegistry.ts +251 -0
- package/components/status/api.ts +153 -0
- package/components/status/crossThread.ts +405 -0
- package/components/status/errors.ts +152 -0
- package/components/status/index.ts +44 -0
- package/components/status/internal.ts +65 -0
- package/components/status/registry.ts +12 -0
- package/components/status/types.ts +96 -0
- package/config/RootConfigWatcher.ts +59 -0
- package/config/configHelpers.ts +11 -0
- package/config/configUtils.js +967 -0
- package/config/harperConfigEnvVars.ts +641 -0
- package/dataLayer/CreateAttributeObject.js +25 -0
- package/dataLayer/CreateTableObject.js +11 -0
- package/dataLayer/DataLayerObjects.js +43 -0
- package/dataLayer/DeleteBeforeObject.js +22 -0
- package/dataLayer/DeleteObject.js +25 -0
- package/dataLayer/DropAttributeObject.js +11 -0
- package/dataLayer/GetBackupObject.js +22 -0
- package/dataLayer/InsertObject.js +24 -0
- package/dataLayer/ReadAuditLogObject.js +24 -0
- package/dataLayer/SQLSearch.js +1335 -0
- package/dataLayer/SearchByConditionsObject.js +61 -0
- package/dataLayer/SearchByHashObject.js +21 -0
- package/dataLayer/SearchObject.js +45 -0
- package/dataLayer/SqlSearchObject.js +14 -0
- package/dataLayer/UpdateObject.js +23 -0
- package/dataLayer/UpsertObject.js +23 -0
- package/dataLayer/bulkLoad.js +813 -0
- package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
- package/dataLayer/dataObjects/UpsertObject.js +23 -0
- package/dataLayer/delete.js +164 -0
- package/dataLayer/export.js +381 -0
- package/dataLayer/getBackup.js +40 -0
- package/dataLayer/harperBridge/BridgeMethods.js +81 -0
- package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
- package/dataLayer/harperBridge/harperBridge.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
- package/dataLayer/hdbInfoController.js +254 -0
- package/dataLayer/insert.js +266 -0
- package/dataLayer/readAuditLog.js +59 -0
- package/dataLayer/schema.js +366 -0
- package/dataLayer/schemaDescribe.js +289 -0
- package/dataLayer/search.js +60 -0
- package/dataLayer/transaction.js +17 -0
- package/dataLayer/update.js +124 -0
- package/dist/components/Logger.d.ts +12 -0
- package/dist/components/Logger.js +3 -0
- package/dist/components/Logger.js.map +1 -0
- package/dist/components/Scope.d.ts +14 -4
- package/dist/components/Scope.js +18 -10
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +16 -9
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +2 -2
- package/dist/components/operations.js.map +1 -1
- package/dist/config/configUtils.d.ts +1 -1
- package/dist/config/configUtils.js +1 -1
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/CreateTableObject.d.ts +2 -2
- package/dist/dataLayer/CreateTableObject.js +2 -2
- package/dist/dataLayer/CreateTableObject.js.map +1 -1
- package/dist/dataLayer/delete.d.ts +1 -1
- package/dist/dataLayer/schema.js +6 -5
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +1 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +1 -1
- package/dist/resources/IterableEventQueue.d.ts +1 -1
- package/dist/resources/LMDBTransaction.d.ts +5 -1
- package/dist/resources/Resource.d.ts +1 -1
- package/dist/resources/RocksIndexStore.d.ts +3 -3
- package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
- package/dist/resources/Table.d.ts +15 -6
- package/dist/resources/Table.js +4 -1
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +32 -22
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/analytics/write.js +3 -6
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +3 -3
- package/dist/resources/blob.d.ts +25 -2
- package/dist/resources/databases.d.ts +12 -2
- package/dist/resources/databases.js +22 -19
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/search.js +11 -5
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transaction.d.ts +2 -1
- package/dist/security/auth.js +1 -1
- package/dist/security/auth.js.map +1 -1
- package/dist/security/cryptoHash.d.ts +2 -2
- package/dist/security/jsLoader.js +243 -66
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +4 -5
- package/dist/security/keys.js.map +1 -1
- package/dist/security/user.js +3 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/REST.js +16 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/Server.d.ts +2 -1
- package/dist/server/Server.js.map +1 -1
- package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
- package/dist/server/fastifyRoutes.js +2 -0
- package/dist/server/fastifyRoutes.js.map +1 -1
- package/dist/server/http.js +12 -6
- package/dist/server/http.js.map +1 -1
- package/dist/server/jobs/JobObject.d.ts +3 -3
- package/dist/server/loadRootComponents.js +1 -0
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/operationsServer.js +3 -1
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
- package/dist/server/serverHelpers/Request.d.ts +5 -5
- package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
- package/dist/server/threads/manageThreads.d.ts +2 -2
- package/dist/server/threads/manageThreads.js +50 -35
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -1
- package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
- package/dist/utility/AWS/AWSConnector.d.ts +3 -2
- package/dist/utility/common_utils.d.ts +3 -3
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
- package/dist/utility/globalSchema.d.ts +1 -1
- package/dist/utility/hdbTerms.d.ts +3 -0
- package/dist/utility/hdbTerms.js +3 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/installation.d.ts +2 -4
- package/dist/utility/installation.js.map +1 -1
- package/dist/utility/lmdb/commonUtility.d.ts +1 -0
- package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
- package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
- package/dist/utility/lmdb/searchUtility.d.ts +2 -1
- package/dist/utility/lmdb/writeUtility.d.ts +1 -0
- package/dist/utility/logging/harper_logger.d.ts +6 -6
- package/dist/utility/processManagement/processManagement.d.ts +1 -1
- package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
- package/dist/validation/common_validators.d.ts +4 -3
- package/dist/validation/configValidator.d.ts +3 -2
- package/index.d.ts +56 -0
- package/index.js +41 -0
- package/json/systemSchema.json +373 -0
- package/launchServiceScripts/launchHarperDB.js +3 -0
- package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
- package/package.json +21 -3
- package/resources/DatabaseTransaction.ts +378 -0
- package/resources/ErrorResource.ts +57 -0
- package/resources/IterableEventQueue.ts +94 -0
- package/resources/LMDBTransaction.ts +349 -0
- package/resources/RecordEncoder.ts +702 -0
- package/resources/RequestTarget.ts +134 -0
- package/resources/Resource.ts +789 -0
- package/resources/ResourceInterface.ts +221 -0
- package/resources/ResourceInterfaceV2.ts +53 -0
- package/resources/ResourceV2.ts +67 -0
- package/resources/Resources.ts +162 -0
- package/resources/RocksIndexStore.ts +70 -0
- package/resources/RocksTransactionLogStore.ts +352 -0
- package/resources/Table.ts +4527 -0
- package/resources/analytics/hostnames.ts +72 -0
- package/resources/analytics/metadata.ts +10 -0
- package/resources/analytics/read.ts +252 -0
- package/resources/analytics/write.ts +803 -0
- package/resources/auditStore.ts +556 -0
- package/resources/blob.ts +1268 -0
- package/resources/crdt.ts +125 -0
- package/resources/dataLoader.ts +527 -0
- package/resources/databases.ts +1290 -0
- package/resources/graphql.ts +221 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
- package/resources/indexes/customIndexes.ts +7 -0
- package/resources/indexes/vector.ts +38 -0
- package/resources/jsResource.ts +86 -0
- package/resources/loadEnv.ts +22 -0
- package/resources/login.ts +18 -0
- package/resources/openApi.ts +409 -0
- package/resources/registrationDeprecated.ts +8 -0
- package/resources/replayLogs.ts +136 -0
- package/resources/roles.ts +98 -0
- package/resources/search.ts +1301 -0
- package/resources/tracked.ts +584 -0
- package/resources/transaction.ts +89 -0
- package/resources/transactionBroadcast.ts +258 -0
- package/security/auth.ts +376 -0
- package/security/certificateVerification/certificateVerificationSource.ts +84 -0
- package/security/certificateVerification/configValidation.ts +107 -0
- package/security/certificateVerification/crlVerification.ts +623 -0
- package/security/certificateVerification/index.ts +121 -0
- package/security/certificateVerification/ocspVerification.ts +148 -0
- package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
- package/security/certificateVerification/types.ts +128 -0
- package/security/certificateVerification/verificationConfig.ts +138 -0
- package/security/certificateVerification/verificationUtils.ts +447 -0
- package/security/cryptoHash.js +42 -0
- package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
- package/security/data_objects/PermissionResponseObject.js +115 -0
- package/security/data_objects/PermissionTableResponseObject.js +20 -0
- package/security/fastifyAuth.js +169 -0
- package/security/impersonation.ts +160 -0
- package/security/jsLoader.ts +716 -0
- package/security/keys.js +948 -0
- package/security/permissionsTranslator.js +300 -0
- package/security/role.js +218 -0
- package/security/tokenAuthentication.ts +228 -0
- package/security/user.ts +449 -0
- package/server/DurableSubscriptionsSession.ts +503 -0
- package/server/REST.ts +407 -0
- package/server/Server.ts +89 -0
- package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
- package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
- package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
- package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
- package/server/fastifyRoutes.ts +205 -0
- package/server/graphqlQuerying.ts +700 -0
- package/server/http.ts +640 -0
- package/server/itc/serverHandlers.js +161 -0
- package/server/itc/utility/ITCEventObject.js +10 -0
- package/server/jobs/JobObject.js +24 -0
- package/server/jobs/jobProcess.js +69 -0
- package/server/jobs/jobRunner.js +162 -0
- package/server/jobs/jobs.js +304 -0
- package/server/loadRootComponents.js +44 -0
- package/server/mqtt.ts +485 -0
- package/server/nodeName.ts +75 -0
- package/server/operationsServer.ts +313 -0
- package/server/serverHelpers/Headers.ts +108 -0
- package/server/serverHelpers/JSONStream.ts +269 -0
- package/server/serverHelpers/OperationFunctionObject.ts +13 -0
- package/server/serverHelpers/Request.ts +158 -0
- package/server/serverHelpers/contentTypes.ts +637 -0
- package/server/serverHelpers/requestTimePlugin.js +57 -0
- package/server/serverHelpers/serverHandlers.js +148 -0
- package/server/serverHelpers/serverUtilities.ts +473 -0
- package/server/serverRegistry.ts +8 -0
- package/server/static.ts +187 -0
- package/server/status/definitions.ts +37 -0
- package/server/status/index.ts +125 -0
- package/server/storageReclamation.ts +93 -0
- package/server/threads/itc.js +89 -0
- package/server/threads/manageThreads.js +594 -0
- package/server/threads/socketRouter.ts +360 -0
- package/server/threads/threadServer.js +279 -0
- package/server/throttle.ts +73 -0
- package/sqlTranslator/SelectValidator.js +330 -0
- package/sqlTranslator/alasqlFunctionImporter.js +62 -0
- package/sqlTranslator/deleteTranslator.js +67 -0
- package/sqlTranslator/index.js +242 -0
- package/sqlTranslator/sql_statement_bucket.js +472 -0
- package/static/defaultConfig.yaml +3 -0
- package/studio/web/HDBDogOnly.svg +78 -0
- package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
- package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
- package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
- package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
- package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
- package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
- package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
- package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
- package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
- package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
- package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
- package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
- package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
- package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
- package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
- package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
- package/studio/web/assets/index-BTgXJX9d.js +235 -0
- package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
- package/studio/web/assets/index-C-GXfcup.js +37 -0
- package/studio/web/assets/index-C-GXfcup.js.map +1 -0
- package/studio/web/assets/index-PFlNdimM.js +2 -0
- package/studio/web/assets/index-PFlNdimM.js.map +1 -0
- package/studio/web/assets/index-Y2g_iFpU.css +1 -0
- package/studio/web/assets/index-jiPwkrsB.css +1 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
- package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
- package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
- package/studio/web/fabric-signup-background.webp +0 -0
- package/studio/web/fabric-signup-text.png +0 -0
- package/studio/web/favicon_purple.png +0 -0
- package/studio/web/github-icon.svg +15 -0
- package/studio/web/harper-fabric_black.png +0 -0
- package/studio/web/harper-fabric_white.png +0 -0
- package/studio/web/harper-studio_white.png +0 -0
- package/studio/web/index.html +16 -0
- package/studio/web/running.css +148 -0
- package/studio/web/running.html +147 -0
- package/studio/web/running.js +111 -0
- package/upgrade/UpgradeObjects.js +13 -0
- package/upgrade/directives/directivesController.js +90 -0
- package/upgrade/directivesManager.js +139 -0
- package/upgrade/upgradePrompt.js +124 -0
- package/upgrade/upgradeUtilities.js +28 -0
- package/utility/AWS/AWSConnector.js +29 -0
- package/utility/OperationFunctionCaller.js +63 -0
- package/utility/assignCmdEnvVariables.js +62 -0
- package/utility/common_utils.js +867 -0
- package/utility/environment/environmentManager.js +208 -0
- package/utility/environment/systemInformation.js +355 -0
- package/utility/errors/commonErrors.js +267 -0
- package/utility/errors/hdbError.js +146 -0
- package/utility/functions/date/dateFunctions.js +65 -0
- package/utility/functions/geo.js +355 -0
- package/utility/functions/sql/alaSQLExtension.js +104 -0
- package/utility/globalSchema.js +35 -0
- package/utility/hdbTerms.ts +819 -0
- package/utility/install/checkJWTTokensExist.js +62 -0
- package/utility/install/harperdb.conf +15 -0
- package/utility/install/harperdb.service +14 -0
- package/utility/install/installer.js +635 -0
- package/utility/installation.ts +30 -0
- package/utility/lmdb/DBIDefinition.js +20 -0
- package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
- package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/OpenDBIObject.js +31 -0
- package/utility/lmdb/OpenEnvironmentObject.js +41 -0
- package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
- package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/cleanLMDBMap.js +65 -0
- package/utility/lmdb/commonUtility.js +119 -0
- package/utility/lmdb/deleteUtility.js +128 -0
- package/utility/lmdb/environmentUtility.js +477 -0
- package/utility/lmdb/searchCursorFunctions.js +187 -0
- package/utility/lmdb/searchUtility.js +918 -0
- package/utility/lmdb/terms.js +57 -0
- package/utility/lmdb/writeUtility.js +407 -0
- package/utility/logging/harper_logger.js +876 -0
- package/utility/logging/logRotator.js +157 -0
- package/utility/logging/logger.ts +24 -0
- package/utility/logging/readLog.js +355 -0
- package/utility/logging/transactionLog.js +57 -0
- package/utility/mount_hdb.js +59 -0
- package/utility/npmUtilities.js +102 -0
- package/utility/operationPermissions.ts +112 -0
- package/utility/operation_authorization.js +836 -0
- package/utility/packageUtils.js +55 -0
- package/utility/password.ts +99 -0
- package/utility/processManagement/processManagement.js +187 -0
- package/utility/processManagement/servicesConfig.js +56 -0
- package/utility/scripts/restartHdb.js +24 -0
- package/utility/scripts/user_data.sh +13 -0
- package/utility/signalling.js +36 -0
- package/utility/terms/certificates.js +81 -0
- package/utility/when.ts +20 -0
- package/v1.d.ts +39 -0
- package/v1.js +41 -0
- package/v2.d.ts +39 -0
- package/v2.js +41 -0
- package/validation/bulkDeleteValidator.js +24 -0
- package/validation/check_permissions.js +19 -0
- package/validation/common_validators.js +95 -0
- package/validation/configValidator.js +331 -0
- package/validation/deleteValidator.js +15 -0
- package/validation/fileLoadValidator.js +153 -0
- package/validation/insertValidator.js +40 -0
- package/validation/installValidator.js +37 -0
- package/validation/readLogValidator.js +64 -0
- package/validation/role_validation.js +320 -0
- package/validation/schemaMetadataValidator.js +42 -0
- package/validation/searchValidator.js +166 -0
- package/validation/statusValidator.ts +66 -0
- package/validation/transactionLogValidator.js +33 -0
- package/validation/user_validation.js +55 -0
- package/validation/validationWrapper.js +105 -0
- package/dist/resources/analytics/profile.d.ts +0 -2
- package/dist/resources/analytics/profile.js +0 -144
- package/dist/resources/analytics/profile.js.map +0 -1
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module is responsible for handling metadata encoding and decoding in database records, which is
|
|
3
|
+
* used for local timestamps (that lmdb-js can assign during a transaction for guaranteed monotonic
|
|
4
|
+
* assignment across threads) and can be used for storing residency information as well. This
|
|
5
|
+
* patches the primary store to properly get the metadata and assign it to the entries.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Encoder } from 'msgpackr';
|
|
9
|
+
import {
|
|
10
|
+
HAS_PREVIOUS_RESIDENCY_ID,
|
|
11
|
+
HAS_CURRENT_RESIDENCY_ID,
|
|
12
|
+
HAS_EXPIRATION_EXTENDED_TYPE,
|
|
13
|
+
HAS_ORIGINATING_OPERATION,
|
|
14
|
+
HAS_BLOBS,
|
|
15
|
+
ACTION_32_BIT,
|
|
16
|
+
HAS_ADDITIONAL_AUDIT_REFS as HAS_ADDITIONAL_AUDIT_REFS_AUDIT,
|
|
17
|
+
} from './auditStore.ts';
|
|
18
|
+
import * as harperLogger from '../utility/logging/harper_logger.js';
|
|
19
|
+
import './blob.ts';
|
|
20
|
+
import { blobsWereEncoded, decodeFromDatabase, deleteBlobsInObject, encodeBlobsWithFilePath } from './blob.ts';
|
|
21
|
+
import { recordAction } from './analytics/write.ts';
|
|
22
|
+
import { RocksDatabase } from '@harperfast/rocksdb-js';
|
|
23
|
+
import { when } from '../utility/when.ts';
|
|
24
|
+
export type Entry = {
|
|
25
|
+
key: any;
|
|
26
|
+
value: any;
|
|
27
|
+
version: number;
|
|
28
|
+
localTime: number;
|
|
29
|
+
expiresAt: number;
|
|
30
|
+
metadataFlags: number;
|
|
31
|
+
nodeId: number;
|
|
32
|
+
residencyId: number;
|
|
33
|
+
size: number;
|
|
34
|
+
deref?: () => any;
|
|
35
|
+
additionalAuditRefs?: Array<{ version: number; nodeId: number }>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// these are matched by lmdb-js for timestamp replacement. the first byte here is used to xor with the first byte of the date as a double so that it ends up less than 32 for easier identification (otherwise dates start with 66)
|
|
39
|
+
export const TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 4, 0x40, 0, 0]);
|
|
40
|
+
// the first byte here indicates that we use the last timestamp
|
|
41
|
+
export const LAST_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 1, 0, 0, 0]);
|
|
42
|
+
export const PREVIOUS_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 3, 0x40, 0, 0]);
|
|
43
|
+
export const NEW_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 0, 0x40, 0, 0]);
|
|
44
|
+
export const LOCAL_TIMESTAMP = Symbol('local-timestamp');
|
|
45
|
+
export const METADATA = Symbol('metadata');
|
|
46
|
+
export const ENTRY = Symbol('entry');
|
|
47
|
+
const TIMESTAMP_HOLDER = new Uint8Array(8);
|
|
48
|
+
const TIMESTAMP_VIEW = new DataView(TIMESTAMP_HOLDER.buffer, 0, 8);
|
|
49
|
+
export const NO_TIMESTAMP = 0;
|
|
50
|
+
export const TIMESTAMP_ASSIGN_NEW = 0;
|
|
51
|
+
export const TIMESTAMP_ASSIGN_LAST = 1;
|
|
52
|
+
export const TIMESTAMP_ASSIGN_PREVIOUS = 3;
|
|
53
|
+
export const TIMESTAMP_RECORD_PREVIOUS = 4;
|
|
54
|
+
export const HAS_EXPIRATION = 16;
|
|
55
|
+
export const HAS_RESIDENCY_ID = 32;
|
|
56
|
+
export const HAS_NODE_ID = 64;
|
|
57
|
+
export const PENDING_LOCAL_TIME = 1;
|
|
58
|
+
export const HAS_STRUCTURE_UPDATE = 0x100;
|
|
59
|
+
export const HAS_ADDITIONAL_AUDIT_REFS = 0x80;
|
|
60
|
+
|
|
61
|
+
const TRACKED_WRITE_TYPES = new Set(['put', 'patch', 'delete', 'message', 'publish']);
|
|
62
|
+
// For now we use this as the private property mechanism for mapping records to entries.
|
|
63
|
+
// WeakMaps are definitely not the fastest form of private properties, but they are the only
|
|
64
|
+
// way to do this with how the objects are frozen for now.
|
|
65
|
+
export const entryMap = new WeakMap<any, Entry>();
|
|
66
|
+
let lastValueEncoding,
|
|
67
|
+
timestampNextEncoding = 0,
|
|
68
|
+
metadataInNextEncoding = -1,
|
|
69
|
+
expiresAtNextEncoding = -1,
|
|
70
|
+
residencyIdAtNextEncoding = 0,
|
|
71
|
+
nodeIdAtNextEncoding = -1,
|
|
72
|
+
additionalAuditRefsNextEncoding: Array<{ version: number; nodeId: number }> | undefined;
|
|
73
|
+
// tracking metadata with a singleton works better than trying to alter response of getEntry/get and coordinating that across caching layers
|
|
74
|
+
export let lastMetadata: Entry | null = null;
|
|
75
|
+
export class RecordEncoder extends Encoder {
|
|
76
|
+
structureUpdate?: any;
|
|
77
|
+
isRocksDB: boolean;
|
|
78
|
+
name: string;
|
|
79
|
+
constructor(options) {
|
|
80
|
+
options.useBigIntExtension = true;
|
|
81
|
+
/**
|
|
82
|
+
* The base class for records that provides the read-only methods for accessing
|
|
83
|
+
* metadata and will be assigned computed property getters. On its own, these instances
|
|
84
|
+
* are usually frozen, but this can be extended (by the Updatable class) for providing
|
|
85
|
+
* mutation methods.
|
|
86
|
+
*/
|
|
87
|
+
class RecordObject {
|
|
88
|
+
getUpdatedTime() {
|
|
89
|
+
return entryMap.get(this)?.version;
|
|
90
|
+
}
|
|
91
|
+
getExpiresAt() {
|
|
92
|
+
return entryMap.get(this)?.expiresAt;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
options.structPrototype = RecordObject.prototype;
|
|
97
|
+
super(options);
|
|
98
|
+
const superEncode = this.encode;
|
|
99
|
+
this.encode = function (record, options?) {
|
|
100
|
+
// this handles our custom metadata encoding, prefixing the record with metadata, including the local
|
|
101
|
+
// timestamp into the audit record, invalidation status and residency information
|
|
102
|
+
if (timestampNextEncoding || metadataInNextEncoding >= 0) {
|
|
103
|
+
let valueStart = 0;
|
|
104
|
+
const timestamp = timestampNextEncoding;
|
|
105
|
+
if (timestamp) {
|
|
106
|
+
valueStart += 8; // make room for local timestamp
|
|
107
|
+
timestampNextEncoding = 0;
|
|
108
|
+
}
|
|
109
|
+
let metadata = metadataInNextEncoding;
|
|
110
|
+
const expiresAt = expiresAtNextEncoding;
|
|
111
|
+
const residencyId = residencyIdAtNextEncoding;
|
|
112
|
+
const nodeId = nodeIdAtNextEncoding;
|
|
113
|
+
const additionalAuditRefs = additionalAuditRefsNextEncoding;
|
|
114
|
+
if (metadata >= 0) {
|
|
115
|
+
valueStart += 4; // make room for metadata bytes
|
|
116
|
+
metadataInNextEncoding = -1; // reset indicator to mean no metadata
|
|
117
|
+
if (expiresAt >= 0) {
|
|
118
|
+
valueStart += 8; // make room for expiration timestamp
|
|
119
|
+
expiresAtNextEncoding = -1; // reset indicator to mean no expiration
|
|
120
|
+
if (!(metadata & HAS_EXPIRATION)) {
|
|
121
|
+
throw new Error('Expiration included, but not in metadata flags');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (residencyId) {
|
|
125
|
+
valueStart += 4; // make room for residency id
|
|
126
|
+
residencyIdAtNextEncoding = 0; // reset indicator to mean no residency id
|
|
127
|
+
if (!(metadata & HAS_RESIDENCY_ID)) {
|
|
128
|
+
throw new Error('Residency id included, but not in metadata flags');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (nodeId >= 0) {
|
|
132
|
+
valueStart += 4; // make room for node id
|
|
133
|
+
nodeIdAtNextEncoding = -1; // reset indicator to mean no node id
|
|
134
|
+
if (!(metadata & HAS_NODE_ID)) {
|
|
135
|
+
throw new Error('Node id included, but not in metadata flags');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (additionalAuditRefs && additionalAuditRefs.length > 0) {
|
|
139
|
+
valueStart += 1 + additionalAuditRefs.length * 12; // 1 byte for count + 8 bytes version + 4 bytes nodeId per ref
|
|
140
|
+
additionalAuditRefsNextEncoding = undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const encoded = superEncode.call(this, record, options | 2048 | valueStart); // encode with 8 bytes reserved space for txnId
|
|
144
|
+
lastValueEncoding = encoded.subarray((encoded.start || 0) + valueStart, encoded.end);
|
|
145
|
+
let position = encoded.start || 0;
|
|
146
|
+
const dataView =
|
|
147
|
+
encoded.dataView || (encoded.dataView = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength));
|
|
148
|
+
if (timestamp) {
|
|
149
|
+
if (this.isRocksDB) {
|
|
150
|
+
// rocksdb, just store the version directly as the timestamp
|
|
151
|
+
dataView.setFloat64(position, timestamp);
|
|
152
|
+
} else {
|
|
153
|
+
// we apply the special instruction bytes that tell lmdb-js how to assign the timestamp
|
|
154
|
+
TIMESTAMP_PLACEHOLDER[4] = timestamp;
|
|
155
|
+
TIMESTAMP_PLACEHOLDER[5] = timestamp >> 8;
|
|
156
|
+
encoded.set(TIMESTAMP_PLACEHOLDER, position);
|
|
157
|
+
}
|
|
158
|
+
position += 8;
|
|
159
|
+
}
|
|
160
|
+
if (blobsWereEncoded) metadata |= HAS_BLOBS;
|
|
161
|
+
if (additionalAuditRefs && additionalAuditRefs.length > 0) metadata |= HAS_ADDITIONAL_AUDIT_REFS;
|
|
162
|
+
if (metadata >= 0) {
|
|
163
|
+
dataView.setUint32(position, metadata | (ACTION_32_BIT << 24)); // use the extended action byte
|
|
164
|
+
position += 4;
|
|
165
|
+
if (expiresAt >= 0) {
|
|
166
|
+
dataView.setFloat64(position, expiresAt);
|
|
167
|
+
position += 8;
|
|
168
|
+
}
|
|
169
|
+
if (residencyId) {
|
|
170
|
+
dataView.setUint32(position, residencyId);
|
|
171
|
+
position += 4;
|
|
172
|
+
}
|
|
173
|
+
if (nodeId >= 0) {
|
|
174
|
+
dataView.setUint32(position, nodeId);
|
|
175
|
+
position += 4;
|
|
176
|
+
}
|
|
177
|
+
if (additionalAuditRefs && additionalAuditRefs.length > 0) {
|
|
178
|
+
encoded[position++] = additionalAuditRefs.length;
|
|
179
|
+
for (const ref of additionalAuditRefs) {
|
|
180
|
+
dataView.setFloat64(position, ref.version);
|
|
181
|
+
position += 8;
|
|
182
|
+
dataView.setUint32(position, ref.nodeId);
|
|
183
|
+
position += 4;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return encoded;
|
|
188
|
+
} else {
|
|
189
|
+
lastValueEncoding = superEncode.call(this, record, options);
|
|
190
|
+
return lastValueEncoding;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const superSaveStructures = this.saveStructures;
|
|
194
|
+
const superGetStructures = this.getStructures;
|
|
195
|
+
this.saveStructures = function (structures, isCompatible): boolean | undefined {
|
|
196
|
+
if (this.isRocksDB) {
|
|
197
|
+
return this.rootStore.transactionSync((txn) => {
|
|
198
|
+
const sharedStructuresKey = [Symbol.for('structures'), this.name];
|
|
199
|
+
const existingStructuresBuffer = txn.getBinarySync(sharedStructuresKey);
|
|
200
|
+
const existingStructures = existingStructuresBuffer ? this.decode(existingStructuresBuffer) : undefined;
|
|
201
|
+
if (typeof isCompatible == 'function') {
|
|
202
|
+
if (!isCompatible(existingStructures)) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
} else if (existingStructures && existingStructures.length !== isCompatible) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
txn.putSync(sharedStructuresKey, structures);
|
|
209
|
+
this.structureUpdate = structures;
|
|
210
|
+
});
|
|
211
|
+
} else {
|
|
212
|
+
const result = superSaveStructures.call(this, structures, isCompatible);
|
|
213
|
+
this.structureUpdate = structures;
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
this.getStructures = function (): any {
|
|
218
|
+
if (this.isRocksDB) {
|
|
219
|
+
const sharedStructuresKey = [Symbol.for('structures'), this.name];
|
|
220
|
+
const buffer = this.rootStore.getBinarySync(sharedStructuresKey);
|
|
221
|
+
return buffer ? this.decode(buffer) : undefined;
|
|
222
|
+
} else {
|
|
223
|
+
return superGetStructures.call(this);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
decode(buffer, options) {
|
|
228
|
+
lastMetadata = null;
|
|
229
|
+
const start = options?.start || 0;
|
|
230
|
+
const end = options > -1 ? options : options?.end || buffer.length;
|
|
231
|
+
let nextByte = buffer[start];
|
|
232
|
+
let metadataFlags = 0;
|
|
233
|
+
try {
|
|
234
|
+
if ((this.isRocksDB && nextByte === 66) || (nextByte < 32 && end > 2)) {
|
|
235
|
+
// record with metadata
|
|
236
|
+
// this means that the record starts with a local timestamp (that was assigned by lmdb-js).
|
|
237
|
+
// we copy it so we can decode it as float-64; we need to do it first because if structural data
|
|
238
|
+
// is loaded during decoding the buffer can actually mutate
|
|
239
|
+
let position = start;
|
|
240
|
+
let localTime;
|
|
241
|
+
if (this.isRocksDB) {
|
|
242
|
+
buffer.copy(TIMESTAMP_HOLDER, 0, position);
|
|
243
|
+
position += 8;
|
|
244
|
+
localTime = TIMESTAMP_VIEW.getFloat64(0);
|
|
245
|
+
nextByte = buffer[position];
|
|
246
|
+
} else if (nextByte === 2) {
|
|
247
|
+
if (buffer.copy) {
|
|
248
|
+
buffer.copy(TIMESTAMP_HOLDER, 0, position);
|
|
249
|
+
position += 8;
|
|
250
|
+
} else {
|
|
251
|
+
for (let i = 0; i < 8; i++) TIMESTAMP_HOLDER[i] = buffer[position++];
|
|
252
|
+
}
|
|
253
|
+
localTime = getTimestamp();
|
|
254
|
+
nextByte = buffer[position];
|
|
255
|
+
}
|
|
256
|
+
let expiresAt, residencyId, nodeId, additionalAuditRefs;
|
|
257
|
+
if (nextByte < 32) {
|
|
258
|
+
if (nextByte === ACTION_32_BIT) {
|
|
259
|
+
const dataView =
|
|
260
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
261
|
+
metadataFlags = dataView.getUint32(position);
|
|
262
|
+
position += 4;
|
|
263
|
+
} else {
|
|
264
|
+
metadataFlags = nextByte | (buffer[position + 1] << 5);
|
|
265
|
+
position += 2;
|
|
266
|
+
}
|
|
267
|
+
if (metadataFlags & HAS_EXPIRATION) {
|
|
268
|
+
const dataView =
|
|
269
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
270
|
+
expiresAt = dataView.getFloat64(position);
|
|
271
|
+
position += 8;
|
|
272
|
+
}
|
|
273
|
+
if (metadataFlags & HAS_RESIDENCY_ID) {
|
|
274
|
+
// we need to read the residency id
|
|
275
|
+
const dataView =
|
|
276
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
277
|
+
residencyId = dataView.getUint32(position);
|
|
278
|
+
position += 4;
|
|
279
|
+
}
|
|
280
|
+
if (metadataFlags & HAS_NODE_ID) {
|
|
281
|
+
// we need to read the node id
|
|
282
|
+
const dataView =
|
|
283
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
284
|
+
nodeId = dataView.getUint32(position);
|
|
285
|
+
position += 4;
|
|
286
|
+
}
|
|
287
|
+
if (metadataFlags & HAS_ADDITIONAL_AUDIT_REFS) {
|
|
288
|
+
// we need to read the additional audit refs
|
|
289
|
+
const dataView =
|
|
290
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
291
|
+
const count = buffer[position++];
|
|
292
|
+
additionalAuditRefs = [];
|
|
293
|
+
for (let i = 0; i < count; i++) {
|
|
294
|
+
const version = dataView.getFloat64(position);
|
|
295
|
+
position += 8;
|
|
296
|
+
const refNodeId = dataView.getUint32(position);
|
|
297
|
+
position += 4;
|
|
298
|
+
additionalAuditRefs.push({ version, nodeId: refNodeId });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const value = decodeFromDatabase(
|
|
304
|
+
() =>
|
|
305
|
+
options?.valueAsBuffer
|
|
306
|
+
? buffer.subarray(position, end)
|
|
307
|
+
: super.decode(buffer.subarray(position, end), end - position),
|
|
308
|
+
this.rootStore
|
|
309
|
+
);
|
|
310
|
+
lastMetadata = {
|
|
311
|
+
localTime,
|
|
312
|
+
version: localTime,
|
|
313
|
+
[METADATA]: metadataFlags,
|
|
314
|
+
expiresAt,
|
|
315
|
+
residencyId,
|
|
316
|
+
nodeId,
|
|
317
|
+
additionalAuditRefs,
|
|
318
|
+
size: end - start,
|
|
319
|
+
value,
|
|
320
|
+
};
|
|
321
|
+
if (this.isRocksDB) return lastMetadata;
|
|
322
|
+
return value;
|
|
323
|
+
} // else a normal entry
|
|
324
|
+
return options?.valueAsBuffer ? buffer : decodeFromDatabase(() => super.decode(buffer, options), this.rootStore);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
harperLogger.error('Error decoding record', error, 'data: ' + buffer.slice(0, 40).toString('hex'));
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function getTimestamp() {
|
|
332
|
+
TIMESTAMP_HOLDER[0] = TIMESTAMP_HOLDER[0] ^ 0x40; // restore the first byte, we xor to differentiate the first byte from structures
|
|
333
|
+
return TIMESTAMP_VIEW.getFloat64(0);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function handleLocalTimeForGets(store, rootStore) {
|
|
337
|
+
const isRocksDB = store instanceof RocksDatabase;
|
|
338
|
+
store.readCount = 0;
|
|
339
|
+
store.cachePuts = false;
|
|
340
|
+
store.rootStore = rootStore;
|
|
341
|
+
store.encoder.rootStore = rootStore;
|
|
342
|
+
store.encoder.isRocksDB = isRocksDB;
|
|
343
|
+
store.decoder = store.encoder;
|
|
344
|
+
const storeGetEntry = store.getEntry;
|
|
345
|
+
const storeGetSync = store.getSync;
|
|
346
|
+
const storeGet = store.get;
|
|
347
|
+
|
|
348
|
+
store.getEntry = function (id, options) {
|
|
349
|
+
store.readCount++;
|
|
350
|
+
lastMetadata = null;
|
|
351
|
+
if (isRocksDB) {
|
|
352
|
+
return when(
|
|
353
|
+
options?.async ? storeGet.call(store, id, options) : storeGetSync.call(store, id, options),
|
|
354
|
+
(entry) => {
|
|
355
|
+
if (entry) {
|
|
356
|
+
if (entry[METADATA]) {
|
|
357
|
+
entry.metadataFlags = entry[METADATA];
|
|
358
|
+
return withEntry(entry);
|
|
359
|
+
} else return { value: entry };
|
|
360
|
+
} else return entry;
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
} else {
|
|
364
|
+
let entry: Entry = storeGetEntry.call(this, id, options);
|
|
365
|
+
if (lastMetadata) {
|
|
366
|
+
entry.metadataFlags = lastMetadata[METADATA];
|
|
367
|
+
entry.localTime = lastMetadata.localTime;
|
|
368
|
+
entry.residencyId = lastMetadata.residencyId;
|
|
369
|
+
entry.nodeId = lastMetadata.nodeId;
|
|
370
|
+
entry.additionalAuditRefs = lastMetadata.additionalAuditRefs;
|
|
371
|
+
entry.size = lastMetadata.size;
|
|
372
|
+
if (lastMetadata.expiresAt >= 0) {
|
|
373
|
+
entry.expiresAt = lastMetadata.expiresAt;
|
|
374
|
+
}
|
|
375
|
+
if (isRocksDB) entry.version = lastMetadata.localTime;
|
|
376
|
+
if (entry.value) {
|
|
377
|
+
entryMap.set(entry.value, entry); // allow the record to access the entry
|
|
378
|
+
}
|
|
379
|
+
entry.key = id;
|
|
380
|
+
}
|
|
381
|
+
return entry && withEntry(entry);
|
|
382
|
+
}
|
|
383
|
+
// if we have decoded with metadata, we want to pull it out and assign to this entry
|
|
384
|
+
function withEntry(entry) {
|
|
385
|
+
if (entry.value) {
|
|
386
|
+
if (entry.value.constructor === Object) {
|
|
387
|
+
// if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
|
|
388
|
+
const originalValue = entry.value;
|
|
389
|
+
entry.value = new this.encoder.structPrototype.constructor();
|
|
390
|
+
Object.assign(entry.value, originalValue);
|
|
391
|
+
}
|
|
392
|
+
entryMap.set(entry.value, entry); // allow the record to access the entry
|
|
393
|
+
}
|
|
394
|
+
entry.key = id;
|
|
395
|
+
return entry;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
store.getSync = function (id, options) {
|
|
400
|
+
const entry = store.getEntry(id, options);
|
|
401
|
+
const value = entry?.value;
|
|
402
|
+
if (value) {
|
|
403
|
+
entryMap.set(value, entry);
|
|
404
|
+
}
|
|
405
|
+
return value;
|
|
406
|
+
};
|
|
407
|
+
store.get = function (id, options) {
|
|
408
|
+
return when(store.getEntry(id, { ...options, async: true }), (entry) => {
|
|
409
|
+
const value = entry?.value;
|
|
410
|
+
if (value) {
|
|
411
|
+
entryMap.set(value, entry);
|
|
412
|
+
}
|
|
413
|
+
return value;
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
//store.pendingTimestampUpdates = new Map();
|
|
418
|
+
const storeGetRange = store.getRange;
|
|
419
|
+
store.getRange = function (options) {
|
|
420
|
+
const iterable = storeGetRange.call(this, options);
|
|
421
|
+
if (options.valuesForKey) {
|
|
422
|
+
return iterable.map((value) => value?.value);
|
|
423
|
+
}
|
|
424
|
+
if (options.values === false || options.onlyCount) return iterable;
|
|
425
|
+
return iterable.map((entry) => {
|
|
426
|
+
// if we have metadata, move the metadata to the entry
|
|
427
|
+
if (isRocksDB) {
|
|
428
|
+
if (entry.value?.[METADATA]) {
|
|
429
|
+
entry.metadataFlags = entry.value[METADATA];
|
|
430
|
+
Object.assign(entry, entry.value);
|
|
431
|
+
}
|
|
432
|
+
} else if (lastMetadata) {
|
|
433
|
+
entry.metadataFlags = lastMetadata[METADATA];
|
|
434
|
+
entry.localTime = lastMetadata.localTime;
|
|
435
|
+
if (isRocksDB) entry.version = lastMetadata.localTime;
|
|
436
|
+
entry.residencyId = lastMetadata.residencyId;
|
|
437
|
+
entry.nodeId = lastMetadata.nodeId;
|
|
438
|
+
entry.additionalAuditRefs = lastMetadata.additionalAuditRefs;
|
|
439
|
+
entry.size = lastMetadata.size;
|
|
440
|
+
if (lastMetadata.expiresAt >= 0) entry.expiresAt = lastMetadata.expiresAt;
|
|
441
|
+
lastMetadata = null;
|
|
442
|
+
}
|
|
443
|
+
if (entry.value) {
|
|
444
|
+
if (entry.value.constructor === Object) {
|
|
445
|
+
// if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
|
|
446
|
+
const originalValue = entry.value;
|
|
447
|
+
entry.value = new this.encoder.structPrototype.constructor();
|
|
448
|
+
for (const key in originalValue) entry.value[key] = originalValue[key];
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return entry;
|
|
452
|
+
});
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
if (!isRocksDB) {
|
|
456
|
+
// add read transaction tracking
|
|
457
|
+
const txn = store.useReadTransaction();
|
|
458
|
+
txn.done();
|
|
459
|
+
if (!txn.done.isTracked) {
|
|
460
|
+
const Txn = txn.constructor;
|
|
461
|
+
const use = txn.use;
|
|
462
|
+
const done = txn.done;
|
|
463
|
+
Txn.prototype.use = function () {
|
|
464
|
+
if (!this.timerTracked) {
|
|
465
|
+
this.timerTracked = true;
|
|
466
|
+
trackedTxns.push(new WeakRef(this));
|
|
467
|
+
}
|
|
468
|
+
use.call(this);
|
|
469
|
+
};
|
|
470
|
+
Txn.prototype.done = function () {
|
|
471
|
+
done.call(this);
|
|
472
|
+
if (this.isDone) {
|
|
473
|
+
for (let i = 0; i < trackedTxns.length; i++) {
|
|
474
|
+
const txn = trackedTxns[i].deref();
|
|
475
|
+
if (!txn || txn.isDone || txn.isCommitted) {
|
|
476
|
+
trackedTxns.splice(i--, 1);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
Txn.prototype.done.isTracked = true;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return store;
|
|
486
|
+
}
|
|
487
|
+
const trackedTxns: WeakRef<any>[] = [];
|
|
488
|
+
setInterval(() => {
|
|
489
|
+
for (let i = 0; i < trackedTxns.length; i++) {
|
|
490
|
+
const txn = trackedTxns[i].deref();
|
|
491
|
+
if (!txn || txn.isDone || txn.isCommitted) trackedTxns.splice(i--, 1);
|
|
492
|
+
else if (txn.notCurrent) {
|
|
493
|
+
if (txn.openTimer) {
|
|
494
|
+
if (txn.openTimer > 3) {
|
|
495
|
+
if (txn.openTimer > 60) {
|
|
496
|
+
harperLogger.error(
|
|
497
|
+
'Read transaction detected that has been open too long (over 15 minutes), ending transaction',
|
|
498
|
+
txn
|
|
499
|
+
);
|
|
500
|
+
txn.done();
|
|
501
|
+
} else
|
|
502
|
+
harperLogger.error(
|
|
503
|
+
'Read transaction detected that has been open too long (over one minute), make sure read transactions are quickly closed',
|
|
504
|
+
txn
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
txn.openTimer++;
|
|
508
|
+
} else txn.openTimer = 1;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}, 15000).unref();
|
|
512
|
+
export function recordUpdater(store, tableId, auditStore) {
|
|
513
|
+
return function (
|
|
514
|
+
id,
|
|
515
|
+
record,
|
|
516
|
+
existingEntry,
|
|
517
|
+
newVersion,
|
|
518
|
+
assignMetadata = -1, // when positive, this has a set of metadata flags for the record
|
|
519
|
+
audit?: boolean, // true -> audit this record. false -> do not. null -> retain any audit timestamp
|
|
520
|
+
options?,
|
|
521
|
+
type = 'put',
|
|
522
|
+
resolveRecord?: boolean, // indicates that we are resolving (from source) record that was previously invalidated
|
|
523
|
+
auditRecord?: any
|
|
524
|
+
) {
|
|
525
|
+
const isRocksDB = store instanceof RocksDatabase;
|
|
526
|
+
// determine if and how we apply the local timestamp
|
|
527
|
+
if (isRocksDB) {
|
|
528
|
+
// with rocksdb, we simplify to just storing the singular version/timestamp
|
|
529
|
+
timestampNextEncoding = newVersion;
|
|
530
|
+
} else if (audit == null)
|
|
531
|
+
// if not auditing, there is no local timestamp to reference
|
|
532
|
+
timestampNextEncoding = NO_TIMESTAMP;
|
|
533
|
+
else if (resolveRecord)
|
|
534
|
+
// preserve existing timestamp, if possible
|
|
535
|
+
timestampNextEncoding = existingEntry?.localTime
|
|
536
|
+
? TIMESTAMP_RECORD_PREVIOUS | TIMESTAMP_ASSIGN_PREVIOUS
|
|
537
|
+
: NO_TIMESTAMP;
|
|
538
|
+
else
|
|
539
|
+
timestampNextEncoding = audit // for audit, we need it
|
|
540
|
+
? existingEntry?.localTime // we already have a timestamp, we need to record the previous one in the audit log
|
|
541
|
+
? TIMESTAMP_RECORD_PREVIOUS | 0x4000
|
|
542
|
+
: TIMESTAMP_ASSIGN_NEW | 0x4000 // or just assign a new one
|
|
543
|
+
: NO_TIMESTAMP;
|
|
544
|
+
const expiresAt = options?.expiresAt;
|
|
545
|
+
if (expiresAt >= 0) assignMetadata |= HAS_EXPIRATION;
|
|
546
|
+
metadataInNextEncoding = assignMetadata;
|
|
547
|
+
expiresAtNextEncoding = expiresAt;
|
|
548
|
+
const putOptions: {
|
|
549
|
+
version: number;
|
|
550
|
+
instructedWrite?: boolean;
|
|
551
|
+
ifVersion?: number;
|
|
552
|
+
} = {
|
|
553
|
+
version: newVersion,
|
|
554
|
+
instructedWrite: timestampNextEncoding > 0,
|
|
555
|
+
transaction: options?.transaction,
|
|
556
|
+
};
|
|
557
|
+
let ifVersion;
|
|
558
|
+
let extendedType = 0;
|
|
559
|
+
try {
|
|
560
|
+
let previousResidencyId = existingEntry?.residencyId;
|
|
561
|
+
const residencyId = options?.residencyId; //getResidency(record, previousResidencyId);
|
|
562
|
+
if (residencyId) {
|
|
563
|
+
residencyIdAtNextEncoding = residencyId;
|
|
564
|
+
metadataInNextEncoding |= HAS_RESIDENCY_ID;
|
|
565
|
+
extendedType |= HAS_CURRENT_RESIDENCY_ID;
|
|
566
|
+
} else residencyIdAtNextEncoding = 0;
|
|
567
|
+
const nodeId = options?.nodeId;
|
|
568
|
+
if (nodeId >= 0) {
|
|
569
|
+
nodeIdAtNextEncoding = nodeId;
|
|
570
|
+
metadataInNextEncoding |= HAS_NODE_ID;
|
|
571
|
+
} else nodeIdAtNextEncoding = -1;
|
|
572
|
+
const additionalAuditRefs = options?.additionalAuditRefs;
|
|
573
|
+
if (additionalAuditRefs && additionalAuditRefs.length > 0) {
|
|
574
|
+
additionalAuditRefsNextEncoding = additionalAuditRefs;
|
|
575
|
+
metadataInNextEncoding |= HAS_ADDITIONAL_AUDIT_REFS;
|
|
576
|
+
} else additionalAuditRefsNextEncoding = undefined;
|
|
577
|
+
const previousAdditionalAuditRefs = existingEntry?.additionalAuditRefs;
|
|
578
|
+
if (previousAdditionalAuditRefs && previousAdditionalAuditRefs.length > 0) {
|
|
579
|
+
extendedType |= HAS_ADDITIONAL_AUDIT_REFS_AUDIT;
|
|
580
|
+
}
|
|
581
|
+
if (previousResidencyId !== residencyId) {
|
|
582
|
+
extendedType |= HAS_PREVIOUS_RESIDENCY_ID;
|
|
583
|
+
if (!previousResidencyId) previousResidencyId = 0;
|
|
584
|
+
}
|
|
585
|
+
if (assignMetadata & HAS_EXPIRATION) extendedType |= HAS_EXPIRATION_EXTENDED_TYPE; // we need to record the expiration in the audit log
|
|
586
|
+
if (options?.originatingOperation) extendedType |= HAS_ORIGINATING_OPERATION;
|
|
587
|
+
// we use resolveRecord outside of transaction, so must explicitly make it conditional
|
|
588
|
+
if (resolveRecord) putOptions.ifVersion = ifVersion = existingEntry?.version ?? null;
|
|
589
|
+
if (existingEntry && existingEntry.value && type !== 'message' && existingEntry.metadataFlags & HAS_BLOBS) {
|
|
590
|
+
// delete the old blobs
|
|
591
|
+
deleteBlobsInObject(existingEntry.value);
|
|
592
|
+
}
|
|
593
|
+
let result: Promise<void>;
|
|
594
|
+
if (record !== undefined) {
|
|
595
|
+
result = encodeBlobsWithFilePath(
|
|
596
|
+
() => (isRocksDB ? store.putSync(id, record, putOptions) : store.put(id, record, putOptions)),
|
|
597
|
+
id,
|
|
598
|
+
store.rootStore
|
|
599
|
+
);
|
|
600
|
+
if (blobsWereEncoded) {
|
|
601
|
+
extendedType |= HAS_BLOBS;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (audit) {
|
|
605
|
+
const username = typeof options?.user === 'string' ? options.user : options?.user?.username;
|
|
606
|
+
if (auditRecord) {
|
|
607
|
+
encodeBlobsWithFilePath(() => store.encoder.encode(auditRecord), id, store.rootStore);
|
|
608
|
+
if (blobsWereEncoded) {
|
|
609
|
+
extendedType |= HAS_BLOBS;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (store.encoder?.structureUpdate) {
|
|
613
|
+
extendedType |= HAS_STRUCTURE_UPDATE;
|
|
614
|
+
store.encoder.structureUpdate = null;
|
|
615
|
+
}
|
|
616
|
+
const structureVersion = store.encoder.structures.length + (store.encoder.typedStructs?.length ?? 0);
|
|
617
|
+
const nodeId = options?.nodeId ?? server.replication?.getThisNodeId(auditStore) ?? 0;
|
|
618
|
+
const viaNodeId = options?.viaNodeId ?? nodeId;
|
|
619
|
+
if (resolveRecord && existingEntry?.localTime) {
|
|
620
|
+
const replacingId = existingEntry?.localTime;
|
|
621
|
+
const replacingEntry = auditStore.get(replacingId, tableId, id);
|
|
622
|
+
if (replacingEntry) {
|
|
623
|
+
const previousVersion = replacingEntry.previousVersion;
|
|
624
|
+
result = auditStore[isRocksDB ? 'putSync' : 'put'](
|
|
625
|
+
replacingId,
|
|
626
|
+
{
|
|
627
|
+
version: newVersion,
|
|
628
|
+
tableId,
|
|
629
|
+
recordId: id,
|
|
630
|
+
previousVersion,
|
|
631
|
+
nodeId,
|
|
632
|
+
user: username,
|
|
633
|
+
type,
|
|
634
|
+
encodedRecord: lastValueEncoding,
|
|
635
|
+
extendedType,
|
|
636
|
+
residencyId,
|
|
637
|
+
previousResidencyId,
|
|
638
|
+
expiresAt,
|
|
639
|
+
structureVersion,
|
|
640
|
+
previousAdditionalAuditRefs,
|
|
641
|
+
},
|
|
642
|
+
{ ifVersion: ifVersion, transaction: options.transaction, nodeId, viaNodeId }
|
|
643
|
+
);
|
|
644
|
+
return result;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
result = auditStore[isRocksDB ? 'putSync' : 'put'](
|
|
648
|
+
record === undefined ? NEW_TIMESTAMP_PLACEHOLDER : LAST_TIMESTAMP_PLACEHOLDER,
|
|
649
|
+
{
|
|
650
|
+
version: newVersion,
|
|
651
|
+
tableId,
|
|
652
|
+
recordId: id,
|
|
653
|
+
previousVersion: store instanceof RocksDatabase ? existingEntry?.version : existingEntry?.localTime ? 1 : 0,
|
|
654
|
+
nodeId,
|
|
655
|
+
user: username,
|
|
656
|
+
type,
|
|
657
|
+
encodedRecord: lastValueEncoding,
|
|
658
|
+
extendedType,
|
|
659
|
+
residencyId,
|
|
660
|
+
previousResidencyId,
|
|
661
|
+
expiresAt,
|
|
662
|
+
structureVersion,
|
|
663
|
+
originatingOperation: options?.originatingOperation,
|
|
664
|
+
previousAdditionalAuditRefs,
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
// turn off append flag, as we are concerned this may be related to db corruption issues
|
|
668
|
+
// append: type !== 'invalidate', // for invalidation, we expect the record to be rewritten, so we don't want to necessarily expect pure sequential writes that create full pages
|
|
669
|
+
instructedWrite: true,
|
|
670
|
+
ifVersion,
|
|
671
|
+
transaction: options.transaction,
|
|
672
|
+
nodeId,
|
|
673
|
+
viaNodeId,
|
|
674
|
+
}
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
if (options?.tableToTrack && TRACKED_WRITE_TYPES.has(type)) {
|
|
678
|
+
recordAction(lastValueEncoding?.length ?? 1, 'db-write', options.tableToTrack, null);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return result;
|
|
682
|
+
} catch (error) {
|
|
683
|
+
error.message += ' id: ' + id + ' options: ' + putOptions;
|
|
684
|
+
throw error;
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
export function setAdditionalAuditRefs(refs: Array<{ version: number; nodeId: number }> | undefined) {
|
|
689
|
+
additionalAuditRefsNextEncoding = refs;
|
|
690
|
+
}
|
|
691
|
+
export function removeEntry(store: any, entry: any, existingVersion?: number) {
|
|
692
|
+
if (!entry) return;
|
|
693
|
+
if (entry.value && entry.metadataFlags & HAS_BLOBS) {
|
|
694
|
+
// if it used to have blobs, we need to delete the old blobs
|
|
695
|
+
deleteBlobsInObject(entry.value);
|
|
696
|
+
}
|
|
697
|
+
return store.remove(entry.key, existingVersion);
|
|
698
|
+
}
|
|
699
|
+
export interface RecordObject {
|
|
700
|
+
getUpdatedTime(): number;
|
|
701
|
+
getExpiresAt(): number;
|
|
702
|
+
}
|