@joystick.js/db-canary 0.0.0-canary.2209
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/.build/getFilesToBuild.js +26 -0
- package/.build/getPlatformSafeFilePath.js +6 -0
- package/.build/getPlatformSafePath.js +6 -0
- package/.build/index.js +88 -0
- package/.build/isWindows.js +3 -0
- package/API_KEY +1 -0
- package/README.md +1821 -0
- package/data/data.mdb +0 -0
- package/data/lock.mdb +0 -0
- package/dist/client/database.js +1 -0
- package/dist/client/index.js +1 -0
- package/dist/server/cluster/index.js +1 -0
- package/dist/server/cluster/master.js +20 -0
- package/dist/server/cluster/worker.js +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/lib/api_key_manager.js +9 -0
- package/dist/server/lib/auth_manager.js +1 -0
- package/dist/server/lib/auto_index_manager.js +1 -0
- package/dist/server/lib/backup_manager.js +1 -0
- package/dist/server/lib/connection_manager.js +1 -0
- package/dist/server/lib/disk_utils.js +2 -0
- package/dist/server/lib/http_server.js +405 -0
- package/dist/server/lib/index_manager.js +1 -0
- package/dist/server/lib/load_settings.js +1 -0
- package/dist/server/lib/logger.js +1 -0
- package/dist/server/lib/op_types.js +1 -0
- package/dist/server/lib/operation_dispatcher.js +1 -0
- package/dist/server/lib/operations/admin.js +1 -0
- package/dist/server/lib/operations/bulk_write.js +1 -0
- package/dist/server/lib/operations/create_index.js +1 -0
- package/dist/server/lib/operations/delete_one.js +1 -0
- package/dist/server/lib/operations/drop_index.js +1 -0
- package/dist/server/lib/operations/find.js +1 -0
- package/dist/server/lib/operations/find_one.js +1 -0
- package/dist/server/lib/operations/get_indexes.js +1 -0
- package/dist/server/lib/operations/insert_one.js +1 -0
- package/dist/server/lib/operations/update_one.js +1 -0
- package/dist/server/lib/performance_monitor.js +1 -0
- package/dist/server/lib/query_engine.js +1 -0
- package/dist/server/lib/recovery_manager.js +1 -0
- package/dist/server/lib/replication_manager.js +1 -0
- package/dist/server/lib/safe_json_parse.js +1 -0
- package/dist/server/lib/send_response.js +1 -0
- package/dist/server/lib/tcp_protocol.js +1 -0
- package/dist/server/lib/write_forwarder.js +1 -0
- package/dist/server/lib/write_queue.js +1 -0
- package/increment_version.js +3 -0
- package/logs/.013e15b54597d05db4b4b53ecc37b10c92a72927-audit.json +20 -0
- package/logs/.02de550a67ea0f5961faa2dfd458a4d06f59ebd1-audit.json +20 -0
- package/logs/.03494ba24eb3c72214b4068a77d54b8993bee651-audit.json +20 -0
- package/logs/.06309ec60b339be1259a7993dd09c732f8907fbc-audit.json +20 -0
- package/logs/.0663a04dcfa17285661e5e1b8cfa51f41523b210-audit.json +20 -0
- package/logs/.0f06e6c4c9b824622729e13927587479e5060391-audit.json +20 -0
- package/logs/.16ccf58682ecb22b3e3ec63f0da1b7fe9be56528-audit.json +20 -0
- package/logs/.1fa1a5d02f496474b1ab473524c65c984146a9ad-audit.json +20 -0
- package/logs/.2223c0ae3bea6f0d62c62b1d319cc8634856abb7-audit.json +20 -0
- package/logs/.23dc79ffda3e083665e6f5993f59397adcbf4a46-audit.json +20 -0
- package/logs/.28104f49b03906b189eefd1cd462cb46c3c0af22-audit.json +20 -0
- package/logs/.29cdbf13808abe6a0ce70ee2f2efdd680ce3fd8e-audit.json +20 -0
- package/logs/.2a9889afd071f77f41f5170d08703a0afca866b7-audit.json +20 -0
- package/logs/.2acec3d1940a2bbed487528b703ee5948959a599-audit.json +20 -0
- package/logs/.2fb60ff326338c02bfedbcd0e936444e4a216750-audit.json +20 -0
- package/logs/.318fc7a19530d76a345f030f7cad00dda15300e7-audit.json +20 -0
- package/logs/.3cf27043e19085f908cedc7701e6d013463208ee-audit.json +25 -0
- package/logs/.3d90d785415817fc443402843b7c95f8371adc9b-audit.json +20 -0
- package/logs/.4074bca620375f72966fc52dfd439577727671e5-audit.json +20 -0
- package/logs/.40eecf018417ea80a70ea8ec7a3cc9406bc6334b-audit.json +20 -0
- package/logs/.50e974f1ef7c365fca6a1251b2e2c2252914cb5e-audit.json +20 -0
- package/logs/.52cb7d9e4223cf26ba36006ac26b949a97c7923c-audit.json +20 -0
- package/logs/.54befcdb84c15aad980705a31bcc9f555c3577ab-audit.json +20 -0
- package/logs/.57dfb70e22eddb84db2e3c0ceeefac5c0b9baffa-audit.json +20 -0
- package/logs/.5f0b24705a1eaad4eca4968f2d86f91b3f9be683-audit.json +20 -0
- package/logs/.61ba98fdda7db58576b382fee07904e5db1169d6-audit.json +20 -0
- package/logs/.6235017727ef6b199d569a99d6aa8c8e80a1b475-audit.json +20 -0
- package/logs/.63db16193699219489d218a1ddea5dde3750cae4-audit.json +20 -0
- package/logs/.64fb67dfe14149c9eef728d79bf30a54da809c60-audit.json +20 -0
- package/logs/.669137453368987c1f311b5345342527afb54e50-audit.json +20 -0
- package/logs/.7a71f8c89ea28ae266d356aeff6306e876a30fbb-audit.json +20 -0
- package/logs/.7afbaa90fe9dc3a7d682676f9bb79f9a1b1fd9a6-audit.json +20 -0
- package/logs/.7ca29e322cd05327035de850099e7610864f2347-audit.json +20 -0
- package/logs/.83335ab3347e449dae03455a110aaf7f120d4802-audit.json +20 -0
- package/logs/.8c2487b5fd445d2c8e5c483c80b9fa99bbf1ca58-audit.json +20 -0
- package/logs/.8c8b9dc386922c9f3b4c13251af7052aac1d24c0-audit.json +20 -0
- package/logs/.8d6155d94640c4863301ae0fee5e4e7372a21446-audit.json +20 -0
- package/logs/.944a3119a243deea7c8270d5d9e582bb1d0eaa10-audit.json +20 -0
- package/logs/.9816a845c30fb2909f3b26a23eeb3538ebcad5db-audit.json +20 -0
- package/logs/.9dc08784e38b865488177c26d4af5934555e0323-audit.json +20 -0
- package/logs/.9dd27d2e0e454ac0a37600206d1cac5493b0d7ee-audit.json +20 -0
- package/logs/.a3d486feeac7654c59b547de96600e8849a06d4f-audit.json +20 -0
- package/logs/.a5b811f4def22250f86cc18870d7c4573625df22-audit.json +20 -0
- package/logs/.a61648eb5f830e0b6f508ac35e4f8f629d2ad4c7-audit.json +20 -0
- package/logs/.a89016d507045771b4b5a65656944a9c0f1e528b-audit.json +20 -0
- package/logs/.a99bee160a1c590be959af46bacc02724803f691-audit.json +20 -0
- package/logs/.ada7906d6243fd7da802f03d86c4ae5dd9df6236-audit.json +20 -0
- package/logs/.b518339ee942143b6af983af167f5bbb6983b4de-audit.json +20 -0
- package/logs/.b51b124b166d53c9519017856ea610d61d65fabe-audit.json +20 -0
- package/logs/.b7a6aee19f58e55633d5e4a3709041c47dfff975-audit.json +20 -0
- package/logs/.bd7a8a6ba9c55d557a4867ab53f02e3ec2e1553d-audit.json +20 -0
- package/logs/.c1435dafe453b169d6392b25065f3cf4ab6fbb21-audit.json +20 -0
- package/logs/.c17e1ce043109f77dc2f0e2aa290a9d1ed842c03-audit.json +20 -0
- package/logs/.ca62637ce9540e5a38a2fbedb2115febb6ad308a-audit.json +15 -0
- package/logs/.ccee67b9c176967f8977071409a41f5cb5cd6ad4-audit.json +20 -0
- package/logs/.db24043417ea79a6f14cd947476399e53930b48d-audit.json +20 -0
- package/logs/.e0f12acccb57829f5f33712bb2e2607ecd808147-audit.json +20 -0
- package/logs/.e9b6cc33d0bbd2e644c4e2bf44d177f850016557-audit.json +20 -0
- package/logs/.f15291d434808e3bdca7963ccd2e73893be027e6-audit.json +20 -0
- package/logs/.f4bdf9e21ef84f8a3fae3ffb32bbc39275991351-audit.json +15 -0
- package/logs/.fbac3aefac1e81b4230df5aa50667cb90d51024f-audit.json +20 -0
- package/logs/.fcfd495c0a9169db243f4a4f21878ee02b76413c-audit.json +20 -0
- package/logs/admin-2025-09-12.log +580 -0
- package/logs/admin-2025-09-15.log +283 -0
- package/logs/admin-error-2025-09-12.log +22 -0
- package/logs/admin-error-2025-09-15.log +10 -0
- package/logs/api_key_manager-2025-09-12.log +658 -0
- package/logs/api_key_manager-2025-09-15.log +295 -0
- package/logs/api_key_manager-error-2025-09-12.log +0 -0
- package/logs/api_key_manager-error-2025-09-15.log +0 -0
- package/logs/auth_manager-2025-09-12.log +4432 -0
- package/logs/auth_manager-2025-09-15.log +2000 -0
- package/logs/auth_manager-error-2025-09-12.log +11 -0
- package/logs/auth_manager-error-2025-09-15.log +5 -0
- package/logs/auto_index_manager-2025-09-12.log +84 -0
- package/logs/auto_index_manager-2025-09-15.log +45 -0
- package/logs/auto_index_manager-error-2025-09-12.log +6 -0
- package/logs/auto_index_manager-error-2025-09-15.log +0 -0
- package/logs/backup_manager-2025-09-12.log +198 -0
- package/logs/backup_manager-2025-09-15.log +90 -0
- package/logs/backup_manager-error-2025-09-12.log +198 -0
- package/logs/backup_manager-error-2025-09-15.log +90 -0
- package/logs/bulk_write-2025-09-12.log +66 -0
- package/logs/bulk_write-2025-09-15.log +38 -0
- package/logs/bulk_write-error-2025-09-12.log +0 -0
- package/logs/bulk_write-error-2025-09-15.log +0 -0
- package/logs/connection_manager-2025-09-12.log +2412 -0
- package/logs/connection_manager-2025-09-15.log +1132 -0
- package/logs/connection_manager-error-2025-09-12.log +0 -0
- package/logs/connection_manager-error-2025-09-15.log +0 -0
- package/logs/create_index-2025-09-12.log +302 -0
- package/logs/create_index-2025-09-15.log +158 -0
- package/logs/create_index-error-2025-09-12.log +30 -0
- package/logs/create_index-error-2025-09-15.log +13 -0
- package/logs/delete_one-2025-09-12.log +73 -0
- package/logs/delete_one-2025-09-15.log +43 -0
- package/logs/delete_one-error-2025-09-12.log +0 -0
- package/logs/delete_one-error-2025-09-15.log +0 -0
- package/logs/disk_utils-2025-09-12.log +4954 -0
- package/logs/disk_utils-2025-09-15.log +2446 -0
- package/logs/disk_utils-error-2025-09-12.log +0 -0
- package/logs/disk_utils-error-2025-09-15.log +0 -0
- package/logs/drop_index-2025-09-12.log +41 -0
- package/logs/drop_index-2025-09-15.log +23 -0
- package/logs/drop_index-error-2025-09-12.log +11 -0
- package/logs/drop_index-error-2025-09-15.log +5 -0
- package/logs/find-2025-09-12.log +1050 -0
- package/logs/find-2025-09-15.log +592 -0
- package/logs/find-error-2025-09-12.log +1 -0
- package/logs/find-error-2025-09-15.log +0 -0
- package/logs/find_one-2025-09-12.log +425 -0
- package/logs/find_one-2025-09-15.log +264 -0
- package/logs/find_one-error-2025-09-12.log +5 -0
- package/logs/find_one-error-2025-09-15.log +0 -0
- package/logs/get_indexes-2025-09-12.log +84 -0
- package/logs/get_indexes-2025-09-15.log +56 -0
- package/logs/get_indexes-error-2025-09-12.log +6 -0
- package/logs/get_indexes-error-2025-09-15.log +0 -0
- package/logs/http_server-2025-09-12.log +2772 -0
- package/logs/http_server-2025-09-15.log +1276 -0
- package/logs/http_server-error-2025-09-12.log +212 -0
- package/logs/http_server-error-2025-09-15.log +44 -0
- package/logs/index_manager-2025-09-12.log +5031 -0
- package/logs/index_manager-2025-09-15.log +2909 -0
- package/logs/index_manager-error-2025-09-12.log +80 -0
- package/logs/index_manager-error-2025-09-15.log +38 -0
- package/logs/insert_one-2025-09-12.log +2181 -0
- package/logs/insert_one-2025-09-15.log +1293 -0
- package/logs/insert_one-error-2025-09-12.log +0 -0
- package/logs/insert_one-error-2025-09-15.log +0 -0
- package/logs/master-2025-09-12.log +1882 -0
- package/logs/master-2025-09-15.log +910 -0
- package/logs/master-error-2025-09-12.log +80 -0
- package/logs/master-error-2025-09-15.log +0 -0
- package/logs/operation_dispatcher-2025-09-12.log +751 -0
- package/logs/operation_dispatcher-2025-09-15.log +359 -0
- package/logs/operation_dispatcher-error-2025-09-12.log +33 -0
- package/logs/operation_dispatcher-error-2025-09-15.log +11 -0
- package/logs/performance_monitor-2025-09-12.log +14889 -0
- package/logs/performance_monitor-2025-09-15.log +6803 -0
- package/logs/performance_monitor-error-2025-09-12.log +0 -0
- package/logs/performance_monitor-error-2025-09-15.log +0 -0
- package/logs/query_engine-2025-09-12.log +5310 -0
- package/logs/query_engine-2025-09-15.log +2639 -0
- package/logs/query_engine-error-2025-09-12.log +0 -0
- package/logs/query_engine-error-2025-09-15.log +0 -0
- package/logs/recovery_manager-2025-09-12.log +462 -0
- package/logs/recovery_manager-2025-09-15.log +210 -0
- package/logs/recovery_manager-error-2025-09-12.log +22 -0
- package/logs/recovery_manager-error-2025-09-15.log +10 -0
- package/logs/replication-2025-09-12.log +1923 -0
- package/logs/replication-2025-09-15.log +917 -0
- package/logs/replication-error-2025-09-12.log +33 -0
- package/logs/replication-error-2025-09-15.log +15 -0
- package/logs/server-2025-09-12.log +2601 -0
- package/logs/server-2025-09-15.log +1191 -0
- package/logs/server-error-2025-09-12.log +0 -0
- package/logs/server-error-2025-09-15.log +0 -0
- package/logs/tcp_protocol-2025-09-12.log +22 -0
- package/logs/tcp_protocol-2025-09-15.log +10 -0
- package/logs/tcp_protocol-error-2025-09-12.log +22 -0
- package/logs/tcp_protocol-error-2025-09-15.log +10 -0
- package/logs/test-2025-09-12.log +0 -0
- package/logs/test-2025-09-15.log +0 -0
- package/logs/test-error-2025-09-12.log +0 -0
- package/logs/test-error-2025-09-15.log +0 -0
- package/logs/update_one-2025-09-12.log +173 -0
- package/logs/update_one-2025-09-15.log +118 -0
- package/logs/update_one-error-2025-09-12.log +0 -0
- package/logs/update_one-error-2025-09-15.log +0 -0
- package/logs/worker-2025-09-12.log +1457 -0
- package/logs/worker-2025-09-15.log +695 -0
- package/logs/worker-error-2025-09-12.log +0 -0
- package/logs/worker-error-2025-09-15.log +0 -0
- package/logs/write_forwarder-2025-09-12.log +1956 -0
- package/logs/write_forwarder-2025-09-15.log +932 -0
- package/logs/write_forwarder-error-2025-09-12.log +66 -0
- package/logs/write_forwarder-error-2025-09-15.log +30 -0
- package/logs/write_queue-2025-09-12.log +612 -0
- package/logs/write_queue-2025-09-15.log +301 -0
- package/logs/write_queue-error-2025-09-12.log +184 -0
- package/logs/write_queue-error-2025-09-15.log +83 -0
- package/package.json +48 -0
- package/prompts/01-core-infrastructure.md +56 -0
- package/prompts/02-secondary-indexing.md +65 -0
- package/prompts/03-write-serialization.md +63 -0
- package/prompts/04-enhanced-authentication.md +75 -0
- package/prompts/05-comprehensive-admin-operations.md +75 -0
- package/prompts/06-backup-and-restore-system.md +106 -0
- package/prompts/07-production-safety-features.md +107 -0
- package/prompts/08-tcp-client-library.md +121 -0
- package/prompts/09-api-method-chaining.md +134 -0
- package/prompts/10-automatic-index-creation.md +223 -0
- package/prompts/11-operation-naming-consistency.md +268 -0
- package/prompts/12-tcp-replication-system.md +333 -0
- package/prompts/13-master-read-write-operations.md +57 -0
- package/prompts/14-index-upsert-operations.md +68 -0
- package/prompts/15-client-api-return-types.md +81 -0
- package/prompts/16-server-setup-ui.md +97 -0
- package/prompts/17-emergency-password-change.md +108 -0
- package/prompts/18-joystick-framework-integration.md +116 -0
- package/prompts/19-api-key-authentication-system.md +137 -0
- package/prompts/20-configurable-server-port.md +105 -0
- package/prompts/21-multi-database-support.md +161 -0
- package/prompts/FULL_TEXT_SEARCH.md +293 -0
- package/prompts/PROMPTS.md +158 -0
- package/prompts/README.md +221 -0
- package/prompts/TYPESCRIPT_GENERATION.md +179 -0
- package/src/client/database.js +166 -0
- package/src/client/index.js +752 -0
- package/src/server/cluster/index.js +53 -0
- package/src/server/cluster/master.js +774 -0
- package/src/server/cluster/worker.js +537 -0
- package/src/server/index.js +540 -0
- package/src/server/lib/api_key_manager.js +473 -0
- package/src/server/lib/auth_manager.js +375 -0
- package/src/server/lib/auto_index_manager.js +681 -0
- package/src/server/lib/backup_manager.js +650 -0
- package/src/server/lib/connection_manager.js +218 -0
- package/src/server/lib/disk_utils.js +118 -0
- package/src/server/lib/http_server.js +1165 -0
- package/src/server/lib/index_manager.js +756 -0
- package/src/server/lib/load_settings.js +143 -0
- package/src/server/lib/logger.js +135 -0
- package/src/server/lib/op_types.js +29 -0
- package/src/server/lib/operation_dispatcher.js +268 -0
- package/src/server/lib/operations/admin.js +808 -0
- package/src/server/lib/operations/bulk_write.js +367 -0
- package/src/server/lib/operations/create_index.js +68 -0
- package/src/server/lib/operations/delete_one.js +114 -0
- package/src/server/lib/operations/drop_index.js +58 -0
- package/src/server/lib/operations/find.js +340 -0
- package/src/server/lib/operations/find_one.js +319 -0
- package/src/server/lib/operations/get_indexes.js +52 -0
- package/src/server/lib/operations/insert_one.js +113 -0
- package/src/server/lib/operations/update_one.js +225 -0
- package/src/server/lib/performance_monitor.js +313 -0
- package/src/server/lib/query_engine.js +243 -0
- package/src/server/lib/recovery_manager.js +388 -0
- package/src/server/lib/replication_manager.js +727 -0
- package/src/server/lib/safe_json_parse.js +21 -0
- package/src/server/lib/send_response.js +47 -0
- package/src/server/lib/tcp_protocol.js +130 -0
- package/src/server/lib/write_forwarder.js +636 -0
- package/src/server/lib/write_queue.js +335 -0
- package/test_data/data.mdb +0 -0
- package/test_data/lock.mdb +0 -0
- package/tests/client/index.test.js +1232 -0
- package/tests/server/cluster/cluster.test.js +248 -0
- package/tests/server/cluster/master_read_write_operations.test.js +577 -0
- package/tests/server/index.test.js +651 -0
- package/tests/server/integration/authentication_integration.test.js +294 -0
- package/tests/server/integration/auto_indexing_integration.test.js +268 -0
- package/tests/server/integration/backup_integration.test.js +513 -0
- package/tests/server/integration/indexing_integration.test.js +126 -0
- package/tests/server/integration/production_safety_integration.test.js +358 -0
- package/tests/server/integration/replication_integration.test.js +227 -0
- package/tests/server/integration/write_serialization_integration.test.js +246 -0
- package/tests/server/lib/api_key_manager.test.js +516 -0
- package/tests/server/lib/auth_manager.test.js +317 -0
- package/tests/server/lib/auto_index_manager.test.js +275 -0
- package/tests/server/lib/backup_manager.test.js +238 -0
- package/tests/server/lib/connection_manager.test.js +221 -0
- package/tests/server/lib/disk_utils.test.js +63 -0
- package/tests/server/lib/http_server.test.js +389 -0
- package/tests/server/lib/index_manager.test.js +301 -0
- package/tests/server/lib/load_settings.test.js +107 -0
- package/tests/server/lib/load_settings_port_config.test.js +243 -0
- package/tests/server/lib/logger.test.js +282 -0
- package/tests/server/lib/operations/admin.test.js +638 -0
- package/tests/server/lib/operations/bulk_write.test.js +128 -0
- package/tests/server/lib/operations/create_index.test.js +138 -0
- package/tests/server/lib/operations/delete_one.test.js +52 -0
- package/tests/server/lib/operations/drop_index.test.js +72 -0
- package/tests/server/lib/operations/find.test.js +93 -0
- package/tests/server/lib/operations/find_one.test.js +91 -0
- package/tests/server/lib/operations/get_indexes.test.js +87 -0
- package/tests/server/lib/operations/insert_one.test.js +42 -0
- package/tests/server/lib/operations/update_one.test.js +89 -0
- package/tests/server/lib/performance_monitor.test.js +185 -0
- package/tests/server/lib/query_engine.test.js +46 -0
- package/tests/server/lib/recovery_manager.test.js +414 -0
- package/tests/server/lib/replication_manager.test.js +202 -0
- package/tests/server/lib/safe_json_parse.test.js +45 -0
- package/tests/server/lib/send_response.test.js +155 -0
- package/tests/server/lib/tcp_protocol.test.js +169 -0
- package/tests/server/lib/write_forwarder.test.js +258 -0
- package/tests/server/lib/write_queue.test.js +255 -0
- package/tsconfig.json +30 -0
- package/types/client/index.d.ts +447 -0
- package/types/server/cluster/index.d.ts +28 -0
- package/types/server/cluster/master.d.ts +115 -0
- package/types/server/cluster/worker.d.ts +1 -0
- package/types/server/lib/auth_manager.d.ts +13 -0
- package/types/server/lib/backup_manager.d.ts +43 -0
- package/types/server/lib/connection_manager.d.ts +15 -0
- package/types/server/lib/disk_utils.d.ts +3 -0
- package/types/server/lib/index_manager.d.ts +24 -0
- package/types/server/lib/load_settings.d.ts +4 -0
- package/types/server/lib/logger.d.ts +44 -0
- package/types/server/lib/op_types.d.ts +6 -0
- package/types/server/lib/performance_monitor.d.ts +68 -0
- package/types/server/lib/query_engine.d.ts +10 -0
- package/types/server/lib/safe_json_parse.d.ts +7 -0
- package/types/server/lib/send_response.d.ts +3 -0
- package/types/server/lib/tcp_protocol.d.ts +12 -0
- package/types/server/lib/write_queue.d.ts +2 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Settings management utilities for loading and caching JoystickDB configuration.
|
|
3
|
+
* Provides functions to load, cache, reload, and clear settings from process.env.JOYSTICK_DB_SETTINGS.
|
|
4
|
+
* This allows the database server to be started as a child process with configuration passed via environment variables.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** @type {Object|null} Cached settings object */
|
|
8
|
+
let cached_settings = null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validates port configuration in settings.
|
|
12
|
+
* @param {Object} settings - Settings object to validate
|
|
13
|
+
* @throws {Error} When port configuration is invalid
|
|
14
|
+
*/
|
|
15
|
+
const validate_port_configuration = (settings) => {
|
|
16
|
+
if (settings.port !== undefined) {
|
|
17
|
+
if (!Number.isInteger(settings.port)) {
|
|
18
|
+
throw new Error('Port must be an integer');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (settings.port < 1024) {
|
|
22
|
+
throw new Error('Port must be between 1024 and 65534 (HTTP port will be port + 1)');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const http_port = settings.port + 1;
|
|
26
|
+
if (http_port > 65535) {
|
|
27
|
+
throw new Error(`HTTP port (${http_port}) would exceed maximum port number (65535). Use a lower TCP port.`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (settings.port > 65534) {
|
|
31
|
+
throw new Error('Port must be between 1024 and 65534 (HTTP port will be port + 1)');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Loads JoystickDB settings from process.env.JOYSTICK_DB_SETTINGS and caches them.
|
|
38
|
+
* @returns {Object} Parsed JoystickDB settings object
|
|
39
|
+
* @throws {Error} When environment variable is missing or contains invalid JSON
|
|
40
|
+
*/
|
|
41
|
+
export const load_settings = () => {
|
|
42
|
+
try {
|
|
43
|
+
const raw_settings = process.env.JOYSTICK_DB_SETTINGS;
|
|
44
|
+
|
|
45
|
+
if (!raw_settings) {
|
|
46
|
+
throw new Error('JOYSTICK_DB_SETTINGS environment variable is not set');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const parsed_settings = JSON.parse(raw_settings);
|
|
50
|
+
|
|
51
|
+
// NOTE: Validate port configuration if present.
|
|
52
|
+
validate_port_configuration(parsed_settings);
|
|
53
|
+
|
|
54
|
+
cached_settings = parsed_settings;
|
|
55
|
+
|
|
56
|
+
return cached_settings;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error instanceof SyntaxError) {
|
|
59
|
+
throw new Error(`Invalid JSON in JOYSTICK_DB_SETTINGS environment variable: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
throw new Error(`Failed to load JoystickDB settings: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the cached settings object.
|
|
68
|
+
* @returns {Object} Cached settings object
|
|
69
|
+
* @throws {Error} When settings haven't been loaded yet
|
|
70
|
+
*/
|
|
71
|
+
export const get_settings = () => {
|
|
72
|
+
if (!cached_settings) {
|
|
73
|
+
throw new Error('Settings not loaded. Call load_settings() first.');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return cached_settings;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Reloads settings from process.env.JOYSTICK_DB_SETTINGS, clearing cache first.
|
|
81
|
+
* @returns {Object} Reloaded settings object
|
|
82
|
+
* @throws {Error} When environment variable loading fails
|
|
83
|
+
*/
|
|
84
|
+
export const reload_settings = () => {
|
|
85
|
+
cached_settings = null;
|
|
86
|
+
return load_settings();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Clears the cached settings, forcing next load_settings call to read from environment variable.
|
|
91
|
+
*/
|
|
92
|
+
export const clear_settings_cache = () => {
|
|
93
|
+
cached_settings = null;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Gets the current environment name from NODE_ENV.
|
|
98
|
+
* @returns {string} Current environment name
|
|
99
|
+
*/
|
|
100
|
+
export const get_current_environment = () => {
|
|
101
|
+
return process.env.NODE_ENV || 'development';
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Checks if JoystickDB settings are available in the environment.
|
|
106
|
+
* @returns {boolean} True if JOYSTICK_DB_SETTINGS environment variable is set
|
|
107
|
+
*/
|
|
108
|
+
export const has_settings = () => {
|
|
109
|
+
return !!process.env.JOYSTICK_DB_SETTINGS;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Gets the configured TCP and HTTP ports from settings.
|
|
114
|
+
* @returns {Object} Port configuration with tcp_port and http_port
|
|
115
|
+
* @returns {number} returns.tcp_port - TCP server port
|
|
116
|
+
* @returns {number} returns.http_port - HTTP server port (tcp_port + 1)
|
|
117
|
+
*/
|
|
118
|
+
export const get_port_configuration = () => {
|
|
119
|
+
let tcp_port = 1983; // Default TCP port
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
// NOTE: Try to load settings if they haven't been loaded yet.
|
|
123
|
+
let settings;
|
|
124
|
+
try {
|
|
125
|
+
settings = get_settings();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
// NOTE: Settings not loaded yet, try to load them.
|
|
128
|
+
load_settings();
|
|
129
|
+
settings = get_settings();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (settings.port !== undefined) {
|
|
133
|
+
tcp_port = settings.port;
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
// NOTE: Settings not available or failed to load, use default port.
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
tcp_port,
|
|
141
|
+
http_port: tcp_port + 1
|
|
142
|
+
};
|
|
143
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
import DailyRotateFile from 'winston-daily-rotate-file';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
const log_directory = path.join(__dirname, '../../../logs');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} ContextLogger
|
|
13
|
+
* @property {function(string, Object): void} info - Log info message with context
|
|
14
|
+
* @property {function(string, Object): void} warn - Log warning message with context
|
|
15
|
+
* @property {function(string, Error|Object): void} error - Log error message with context or error object
|
|
16
|
+
* @property {function(string, Object): void} debug - Log debug message with context
|
|
17
|
+
* @property {function(string, number, Object): void} log_operation - Log operation completion with duration
|
|
18
|
+
* @property {function(string, string, Object): void} log_request - Log request with ID and operation
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a Winston logger instance with file rotation and console output.
|
|
23
|
+
* @param {string} [component='server'] - Component name for log identification
|
|
24
|
+
* @returns {Object} Object containing logger instance and context logger factory
|
|
25
|
+
* @returns {winston.Logger} returns.logger - Winston logger instance
|
|
26
|
+
* @returns {function(Object): ContextLogger} returns.create_context_logger - Factory for context loggers
|
|
27
|
+
*/
|
|
28
|
+
const create_logger = (component = 'server') => {
|
|
29
|
+
const logger = winston.createLogger({
|
|
30
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
31
|
+
format: winston.format.combine(
|
|
32
|
+
winston.format.timestamp({
|
|
33
|
+
format: 'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
|
34
|
+
}),
|
|
35
|
+
winston.format.errors({ stack: true }),
|
|
36
|
+
winston.format.json(),
|
|
37
|
+
winston.format.printf((info) => {
|
|
38
|
+
const log_entry = {
|
|
39
|
+
timestamp: info.timestamp,
|
|
40
|
+
level: info.level,
|
|
41
|
+
component: component,
|
|
42
|
+
pid: process.pid,
|
|
43
|
+
message: info.message,
|
|
44
|
+
...info.context && { context: info.context },
|
|
45
|
+
...info.duration_ms && { duration_ms: info.duration_ms },
|
|
46
|
+
...info.request_id && { request_id: info.request_id },
|
|
47
|
+
...info.worker_id && { worker_id: info.worker_id },
|
|
48
|
+
...info.stack && { stack: info.stack }
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return JSON.stringify(log_entry);
|
|
52
|
+
})
|
|
53
|
+
),
|
|
54
|
+
transports: [
|
|
55
|
+
new winston.transports.Console({
|
|
56
|
+
format: winston.format.printf((info) => {
|
|
57
|
+
const log_entry = {
|
|
58
|
+
level: info.level,
|
|
59
|
+
message: info.message,
|
|
60
|
+
...info.context && { context: info.context },
|
|
61
|
+
...info.duration_ms && { duration_ms: info.duration_ms },
|
|
62
|
+
...info.request_id && { request_id: info.request_id },
|
|
63
|
+
...info.worker_id && { worker_id: info.worker_id },
|
|
64
|
+
timestamp: info.timestamp
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return JSON.stringify(log_entry);
|
|
68
|
+
})
|
|
69
|
+
}),
|
|
70
|
+
new DailyRotateFile({
|
|
71
|
+
filename: path.join(log_directory, `${component}-%DATE%.log`),
|
|
72
|
+
datePattern: 'YYYY-MM-DD',
|
|
73
|
+
zippedArchive: true,
|
|
74
|
+
maxSize: '20m',
|
|
75
|
+
maxFiles: '14d',
|
|
76
|
+
format: winston.format.json()
|
|
77
|
+
}),
|
|
78
|
+
new DailyRotateFile({
|
|
79
|
+
filename: path.join(log_directory, `${component}-error-%DATE%.log`),
|
|
80
|
+
datePattern: 'YYYY-MM-DD',
|
|
81
|
+
zippedArchive: true,
|
|
82
|
+
maxSize: '20m',
|
|
83
|
+
maxFiles: '30d',
|
|
84
|
+
level: 'error',
|
|
85
|
+
format: winston.format.json()
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Creates a context logger with predefined base context.
|
|
92
|
+
* @param {Object} [base_context={}] - Base context to include in all log messages
|
|
93
|
+
* @returns {ContextLogger} Context logger with info, warn, error, debug methods
|
|
94
|
+
*/
|
|
95
|
+
const create_context_logger = (base_context = {}) => {
|
|
96
|
+
return {
|
|
97
|
+
info: (message, context = {}) => {
|
|
98
|
+
logger.info(message, { context: { ...base_context, ...context } });
|
|
99
|
+
},
|
|
100
|
+
warn: (message, context = {}) => {
|
|
101
|
+
logger.warn(message, { context: { ...base_context, ...context } });
|
|
102
|
+
},
|
|
103
|
+
error: (message, error_or_context = {}) => {
|
|
104
|
+
if (error_or_context instanceof Error) {
|
|
105
|
+
logger.error(message, {
|
|
106
|
+
context: base_context,
|
|
107
|
+
stack: error_or_context.stack,
|
|
108
|
+
error_message: error_or_context.message
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
logger.error(message, { context: { ...base_context, ...error_or_context } });
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
debug: (message, context = {}) => {
|
|
115
|
+
logger.debug(message, { context: { ...base_context, ...context } });
|
|
116
|
+
},
|
|
117
|
+
log_operation: (operation, duration_ms, context = {}) => {
|
|
118
|
+
logger.info(`Operation completed: ${operation}`, {
|
|
119
|
+
context: { ...base_context, ...context, operation },
|
|
120
|
+
duration_ms
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
log_request: (request_id, operation, context = {}) => {
|
|
124
|
+
logger.info(`Request: ${operation}`, {
|
|
125
|
+
request_id,
|
|
126
|
+
context: { ...base_context, ...context, operation }
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return { logger, create_context_logger };
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export default create_logger;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Supported operation types for JoystickDB server validation.
|
|
3
|
+
*
|
|
4
|
+
* Defines the complete list of valid operation types that the server can handle,
|
|
5
|
+
* used for request validation and operation routing.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Array of supported operation types for the JoystickDB server.
|
|
10
|
+
* @type {string[]}
|
|
11
|
+
*/
|
|
12
|
+
const op_types = [
|
|
13
|
+
"authentication",
|
|
14
|
+
"setup",
|
|
15
|
+
"find_one",
|
|
16
|
+
"find",
|
|
17
|
+
"insert_one",
|
|
18
|
+
"update_one",
|
|
19
|
+
"delete_one",
|
|
20
|
+
"bulk_write",
|
|
21
|
+
"create_index",
|
|
22
|
+
"drop_index",
|
|
23
|
+
"get_indexes",
|
|
24
|
+
"admin",
|
|
25
|
+
"ping",
|
|
26
|
+
"reload",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default op_types;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Central operation dispatcher for routing and handling database and admin operations.
|
|
3
|
+
*
|
|
4
|
+
* Provides unified handling for all database operations (CRUD, indexing) and admin operations
|
|
5
|
+
* with authentication, performance monitoring, replication, and write forwarding support.
|
|
6
|
+
* Manages operation routing, error handling, and response formatting.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { encode_message } from './tcp_protocol.js';
|
|
10
|
+
import { get_write_forwarder } from './write_forwarder.js';
|
|
11
|
+
import { get_replication_manager } from './replication_manager.js';
|
|
12
|
+
import { check_and_grow_map_size } from './query_engine.js';
|
|
13
|
+
import { performance_monitor } from './performance_monitor.js';
|
|
14
|
+
import create_logger from './logger.js';
|
|
15
|
+
import insert_one from './operations/insert_one.js';
|
|
16
|
+
import update_one from './operations/update_one.js';
|
|
17
|
+
import delete_one from './operations/delete_one.js';
|
|
18
|
+
import bulk_write from './operations/bulk_write.js';
|
|
19
|
+
import find_one from './operations/find_one.js';
|
|
20
|
+
import find from './operations/find.js';
|
|
21
|
+
import create_index_operation from './operations/create_index.js';
|
|
22
|
+
import drop_index_operation from './operations/drop_index.js';
|
|
23
|
+
import get_indexes_operation from './operations/get_indexes.js';
|
|
24
|
+
import admin_operation from './operations/admin.js';
|
|
25
|
+
|
|
26
|
+
const { create_context_logger } = create_logger('operation_dispatcher');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Validates database name according to naming rules.
|
|
30
|
+
* @param {string} database_name - Database name to validate
|
|
31
|
+
* @returns {boolean} True if valid, false otherwise
|
|
32
|
+
*/
|
|
33
|
+
const validate_database_name = (database_name) => {
|
|
34
|
+
if (!database_name || typeof database_name !== 'string') {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// NOTE: Check length limit.
|
|
39
|
+
if (database_name.length > 64) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// NOTE: Check for reserved names.
|
|
44
|
+
const reserved_names = ['admin', 'config', 'local'];
|
|
45
|
+
if (reserved_names.includes(database_name.toLowerCase())) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// NOTE: Check naming convention (alphanumeric, underscores, hyphens).
|
|
50
|
+
const valid_name_pattern = /^[a-zA-Z0-9_-]+$/;
|
|
51
|
+
return valid_name_pattern.test(database_name);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Handles database operations (CRUD, indexing) with authentication, logging, and performance monitoring.
|
|
56
|
+
* @param {net.Socket} socket - Client socket connection
|
|
57
|
+
* @param {string} op_type - Type of database operation
|
|
58
|
+
* @param {Object} data - Operation data
|
|
59
|
+
* @param {Function} check_authentication - Function to check if socket is authenticated
|
|
60
|
+
* @param {number} [raw_data_size=0] - Size of raw request data for monitoring
|
|
61
|
+
* @param {Object} [connection_manager] - Connection manager instance (optional)
|
|
62
|
+
* @param {Set} [authenticated_clients] - Set of authenticated client IDs (optional)
|
|
63
|
+
*/
|
|
64
|
+
export const handle_database_operation = async (socket, op_type, data, check_authentication, raw_data_size = 0, connection_manager = null, authenticated_clients = null) => {
|
|
65
|
+
const log = create_context_logger();
|
|
66
|
+
const start_time = Date.now();
|
|
67
|
+
|
|
68
|
+
if (!check_authentication(socket)) {
|
|
69
|
+
const response = { ok: 0, error: 'Authentication required' };
|
|
70
|
+
const encoded_response = encode_message(response);
|
|
71
|
+
socket.write(encoded_response);
|
|
72
|
+
performance_monitor.log_structured_operation(socket.id, op_type, null, 0, 'error', 'Authentication required', raw_data_size, 0);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// NOTE: Extract and validate database name from request.
|
|
77
|
+
const database_name = data.database || 'default';
|
|
78
|
+
|
|
79
|
+
if (!validate_database_name(database_name)) {
|
|
80
|
+
const response = { ok: 0, error: 'Invalid database name. Database names must be alphanumeric with underscores/hyphens, max 64 characters, and cannot be reserved names (admin, config, local).' };
|
|
81
|
+
const encoded_response = encode_message(response);
|
|
82
|
+
socket.write(encoded_response);
|
|
83
|
+
performance_monitor.log_structured_operation(socket.id, op_type, data.collection, 0, 'error', 'Invalid database name', raw_data_size, 0);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// NOTE: Check if this is a secondary node and should forward write operations.
|
|
88
|
+
const write_forwarder = get_write_forwarder();
|
|
89
|
+
const forwarded = await write_forwarder.forward_operation(socket, op_type, data);
|
|
90
|
+
|
|
91
|
+
if (forwarded) {
|
|
92
|
+
// Operation was forwarded to primary, response will be handled by forwarder
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
let result;
|
|
98
|
+
|
|
99
|
+
switch (op_type) {
|
|
100
|
+
case 'insert_one':
|
|
101
|
+
result = await insert_one(database_name, data.collection, data.document, data.options);
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
case 'update_one':
|
|
105
|
+
result = await update_one(database_name, data.collection, data.filter, data.update, data.options);
|
|
106
|
+
break;
|
|
107
|
+
|
|
108
|
+
case 'delete_one':
|
|
109
|
+
result = await delete_one(database_name, data.collection, data.filter, data.options);
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case 'bulk_write':
|
|
113
|
+
result = await bulk_write(database_name, data.collection, data.operations, data.options);
|
|
114
|
+
break;
|
|
115
|
+
|
|
116
|
+
case 'find_one':
|
|
117
|
+
result = await find_one(database_name, data.collection, data.filter, data.options);
|
|
118
|
+
break;
|
|
119
|
+
|
|
120
|
+
case 'find':
|
|
121
|
+
result = await find(database_name, data.collection, data.filter, data.options);
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case 'create_index':
|
|
125
|
+
result = await create_index_operation(database_name, data.collection, data.field, data.options);
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case 'drop_index':
|
|
129
|
+
result = await drop_index_operation(database_name, data.collection, data.field);
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case 'get_indexes':
|
|
133
|
+
result = await get_indexes_operation(database_name, data.collection);
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
default:
|
|
137
|
+
throw new Error(`Unsupported operation: ${op_type}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const duration_ms = Date.now() - start_time;
|
|
141
|
+
|
|
142
|
+
// NOTE: All operations now return structured responses for consistency.
|
|
143
|
+
let response;
|
|
144
|
+
if (op_type === 'find_one') {
|
|
145
|
+
response = { ok: 1, document: result };
|
|
146
|
+
} else if (op_type === 'find') {
|
|
147
|
+
response = { ok: 1, documents: result };
|
|
148
|
+
} else {
|
|
149
|
+
response = { ok: 1, ...result };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const encoded_response = encode_message(response);
|
|
153
|
+
const response_size = encoded_response.length;
|
|
154
|
+
|
|
155
|
+
socket.write(encoded_response);
|
|
156
|
+
|
|
157
|
+
// NOTE: Log structured operation with performance monitoring.
|
|
158
|
+
performance_monitor.log_structured_operation(
|
|
159
|
+
socket.id,
|
|
160
|
+
op_type,
|
|
161
|
+
data.collection,
|
|
162
|
+
duration_ms,
|
|
163
|
+
'success',
|
|
164
|
+
null,
|
|
165
|
+
raw_data_size,
|
|
166
|
+
response_size
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
log.info('Database operation completed', {
|
|
170
|
+
client_id: socket.id,
|
|
171
|
+
op: op_type,
|
|
172
|
+
collection: data.collection,
|
|
173
|
+
duration_ms,
|
|
174
|
+
status: 'success',
|
|
175
|
+
request_size: raw_data_size,
|
|
176
|
+
response_size
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// NOTE: Queue write operations for replication to secondary nodes.
|
|
180
|
+
if (op_type !== 'find' && op_type !== 'find_one' && op_type !== 'get_indexes') {
|
|
181
|
+
const replication_manager = get_replication_manager();
|
|
182
|
+
replication_manager.queue_replication(op_type, data.collection, data);
|
|
183
|
+
|
|
184
|
+
setImmediate(() => check_and_grow_map_size());
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
const duration_ms = Date.now() - start_time;
|
|
188
|
+
|
|
189
|
+
// NOTE: Log structured operation with error.
|
|
190
|
+
performance_monitor.log_structured_operation(
|
|
191
|
+
socket.id,
|
|
192
|
+
op_type,
|
|
193
|
+
data.collection,
|
|
194
|
+
duration_ms,
|
|
195
|
+
'error',
|
|
196
|
+
error.message,
|
|
197
|
+
raw_data_size,
|
|
198
|
+
0
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
log.error('Database operation failed', {
|
|
202
|
+
client_id: socket.id,
|
|
203
|
+
op: op_type,
|
|
204
|
+
collection: data.collection,
|
|
205
|
+
duration_ms,
|
|
206
|
+
status: 'error',
|
|
207
|
+
error: error.message,
|
|
208
|
+
request_size: raw_data_size
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const error_response = { ok: 0, error: error.message };
|
|
212
|
+
const encoded_error_response = encode_message(error_response);
|
|
213
|
+
socket.write(encoded_error_response);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Handles admin operations with authentication and error handling.
|
|
219
|
+
* @param {net.Socket} socket - Client socket connection
|
|
220
|
+
* @param {Object} data - Admin operation data
|
|
221
|
+
* @param {Function} check_authentication - Function to check if socket is authenticated
|
|
222
|
+
* @param {Object} [connection_manager] - Connection manager instance (optional)
|
|
223
|
+
* @param {Set} [authenticated_clients] - Set of authenticated client IDs (optional)
|
|
224
|
+
*/
|
|
225
|
+
export const handle_admin_operation = async (socket, data, check_authentication, connection_manager = null, authenticated_clients = null) => {
|
|
226
|
+
if (!check_authentication(socket)) {
|
|
227
|
+
// NOTE: Unauthenticated admin requests should return ok: false.
|
|
228
|
+
const response = { ok: false, error: 'Authentication required' };
|
|
229
|
+
const encoded_response = encode_message(response);
|
|
230
|
+
socket.write(encoded_response);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
const admin_action = data?.admin_action;
|
|
236
|
+
const admin_data = data || {};
|
|
237
|
+
|
|
238
|
+
const result = await admin_operation(admin_action, admin_data, connection_manager, authenticated_clients);
|
|
239
|
+
|
|
240
|
+
// NOTE: Handle different response formats for admin operations.
|
|
241
|
+
if (!admin_action) {
|
|
242
|
+
// NOTE: Default admin operation (backward compatibility) - return result directly with ok: true.
|
|
243
|
+
const response = { ok: true, ...result };
|
|
244
|
+
const encoded_response = encode_message(response);
|
|
245
|
+
socket.write(encoded_response);
|
|
246
|
+
} else {
|
|
247
|
+
// NOTE: Specific admin actions - return result directly with ok: 1.
|
|
248
|
+
const response = { ok: 1, ...result };
|
|
249
|
+
const encoded_response = encode_message(response);
|
|
250
|
+
socket.write(encoded_response);
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
// NOTE: Admin operation errors use ok: 0.
|
|
254
|
+
const response = { ok: 0, error: `Admin operation failed: ${error.message}` };
|
|
255
|
+
const encoded_response = encode_message(response);
|
|
256
|
+
socket.write(encoded_response);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Handles ping operations.
|
|
262
|
+
* @param {net.Socket} socket - Client socket connection
|
|
263
|
+
*/
|
|
264
|
+
export const handle_ping_operation = (socket) => {
|
|
265
|
+
const ping_response = { ok: 1 };
|
|
266
|
+
const encoded_ping_response = encode_message(ping_response);
|
|
267
|
+
socket.write(encoded_ping_response);
|
|
268
|
+
};
|