rubydb 0.1.4 → 0.1.6
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.
- checksums.yaml +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -15
- data/.github/workflows/benchmark.yml +26 -26
- data/.github/workflows/compatibility.yml +63 -63
- data/.github/workflows/fuzz.yml +33 -33
- data/.github/workflows/lint.yml +21 -21
- data/.github/workflows/operations.yml +24 -24
- data/.github/workflows/production-validation.yml +111 -111
- data/.github/workflows/release.yml +77 -77
- data/.github/workflows/security.yml +39 -37
- data/.github/workflows/test.yml +26 -26
- data/.github/workflows/workload.yml +58 -58
- data/.gitignore +16 -5
- data/.rubocop.yml +50 -44
- data/.standard.yml +9 -14
- data/ARCHITECTURE.md +21 -21
- data/CHANGELOG.md +57 -27
- data/CODE_OF_CONDUCT.md +13 -13
- data/CONTRIBUTING.md +29 -29
- data/GOVERNANCE.md +16 -16
- data/Gemfile +18 -17
- data/Gemfile.lock +125 -71
- data/README.md +168 -12
- data/ROADMAP.md +27 -27
- data/Rakefile +76 -71
- data/SECURITY.md +54 -54
- data/SUPPORT.md +14 -14
- data/accelerator/bin/SHA256SUMS +6 -0
- data/accelerator/bin/rubydb-accelerator-darwin-amd64 +0 -0
- data/accelerator/bin/rubydb-accelerator-darwin-arm64 +0 -0
- data/accelerator/bin/rubydb-accelerator-linux-amd64 +0 -0
- data/accelerator/bin/rubydb-accelerator-linux-arm64 +0 -0
- data/accelerator/bin/rubydb-accelerator-windows-amd64.exe +0 -0
- data/accelerator/bin/rubydb-accelerator-windows-arm64.exe +0 -0
- data/accelerator/cmd/rubydb-accelerator/main.go +11 -0
- data/accelerator/go.mod +3 -0
- data/accelerator/internal/execution/aggregate.go +94 -0
- data/accelerator/internal/execution/distinct.go +22 -0
- data/accelerator/internal/execution/filter.go +73 -0
- data/accelerator/internal/execution/join.go +79 -0
- data/accelerator/internal/execution/operators.go +167 -0
- data/accelerator/internal/execution/scan.go +20 -0
- data/accelerator/internal/execution/sort.go +62 -0
- data/accelerator/internal/execution/types.go +136 -0
- data/accelerator/internal/execution/value.go +67 -0
- data/accelerator/internal/memory/arena.go +47 -0
- data/accelerator/internal/memory/reuse.go +22 -0
- data/accelerator/internal/metrics/registry.go +67 -0
- data/accelerator/internal/parallel/bounded_queue.go +56 -0
- data/accelerator/internal/parallel/scheduler.go +47 -0
- data/accelerator/internal/parallel/worker_pool.go +53 -0
- data/accelerator/internal/protocol/cancellation.go +48 -0
- data/accelerator/internal/protocol/columnar.go +263 -0
- data/accelerator/internal/protocol/frame.go +187 -0
- data/accelerator/internal/runtime/worker.go +521 -0
- data/accelerator/internal/storage/page_reader.go +81 -0
- data/accelerator/internal/storage/snapshot_scan.go +539 -0
- data/accelerator/internal/wal/checksum.go +13 -0
- data/accelerator/internal/wal/compression.go +41 -0
- data/accelerator/internal/wal/group_commit.go +24 -0
- data/accelerator/internal/wal/record_encoder.go +40 -0
- data/adapters/activerecord/Gemfile +11 -11
- data/adapters/activerecord/README.md +8 -3
- data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +881 -879
- data/adapters/activerecord/rubydb-activerecord.gemspec +21 -21
- data/adapters/activerecord/spec/rubydb_adapter_integration_spec.rb +143 -143
- data/adapters/ruby/README.md +18 -18
- data/adapters/sequel/README.md +11 -11
- data/config/monitoring/prometheus-alerts.yml +39 -39
- data/config/production.yml +36 -36
- data/docs/README.md +77 -71
- data/docs/architecture/concurrency.md +14 -14
- data/docs/architecture/current-state.md +125 -125
- data/docs/architecture/execution-engine.md +25 -25
- data/docs/architecture/go-accelerator.md +179 -0
- data/docs/architecture/indexes.md +19 -19
- data/docs/architecture/mvcc.md +19 -19
- data/docs/architecture/overview.md +13 -13
- data/docs/architecture/pages.md +11 -11
- data/docs/architecture/production-roadmap.md +82 -82
- data/docs/architecture/query-planner.md +20 -20
- data/docs/architecture/recovery.md +18 -18
- data/docs/architecture/sql-engine.md +12 -12
- data/docs/architecture/storage-engine.md +14 -14
- data/docs/architecture/transactions.md +10 -10
- data/docs/architecture/wal.md +28 -28
- data/docs/cli-cheatsheet.md +98 -98
- data/docs/cli.md +299 -275
- data/docs/contributing/architecture.md +9 -9
- data/docs/contributing/benchmarking.md +30 -14
- data/docs/contributing/development.md +16 -16
- data/docs/contributing/release-process.md +49 -49
- data/docs/contributing/testing.md +16 -16
- data/docs/debugging.md +229 -229
- data/docs/developer/branching.md +10 -10
- data/docs/developer/database-diff.md +10 -10
- data/docs/developer/local-development.md +49 -17
- data/docs/developer/snapshots.md +9 -9
- data/docs/developer/temporal-data.md +10 -10
- data/docs/developer-guide.md +297 -297
- data/docs/getting-started/first-database.md +16 -16
- data/docs/getting-started/first-query.md +13 -13
- data/docs/getting-started/installation.md +19 -19
- data/docs/getting-started/local-to-production.md +300 -300
- data/docs/getting-started/quickstart.md +17 -17
- data/docs/getting-started/rails.md +16 -16
- data/docs/hardening_backlog.md +93 -93
- data/docs/lessons-learned.md +112 -112
- data/docs/operations/backups.md +33 -33
- data/docs/operations/disaster-recovery.md +31 -31
- data/docs/operations/failover.md +30 -30
- data/docs/operations/monitoring.md +25 -25
- data/docs/operations/production-guide.md +295 -295
- data/docs/operations/production-runbook.md +45 -45
- data/docs/operations/replication.md +33 -33
- data/docs/operations/restore.md +6 -6
- data/docs/operations/runbook.md +34 -34
- data/docs/operations/upgrades.md +14 -14
- data/docs/operations/workload-testing.md +17 -17
- data/docs/production-readiness.md +118 -118
- data/docs/production_validation.md +150 -150
- data/docs/rails/active-record.md +11 -11
- data/docs/rails/compatibility-guide.md +90 -90
- data/docs/rails/database-yml.md +92 -92
- data/docs/rails/installation.md +17 -17
- data/docs/rails/migrations.md +17 -17
- data/docs/rails/production.md +82 -82
- data/docs/rails/troubleshooting.md +18 -18
- data/docs/release.md +25 -25
- data/docs/server/architecture.md +10 -10
- data/docs/server/authentication.md +10 -10
- data/docs/server/configuration.md +16 -16
- data/docs/server/connection-pooling.md +10 -10
- data/docs/server/deployment.md +10 -10
- data/docs/server/protocol.md +12 -12
- data/docs/sql/compatibility-guide.md +82 -82
- data/docs/sql/compatibility.md +39 -39
- data/docs/sql/data-types.md +10 -10
- data/docs/sql/functions.md +9 -9
- data/docs/sql/joins.md +9 -9
- data/docs/sql/operators.md +9 -9
- data/docs/sql/sqlite-compatibility.md +21 -21
- data/docs/sql/syntax.md +10 -10
- data/docs/sql/transactions.md +10 -10
- data/docs/troubleshooting.md +244 -244
- data/lessons/01-foundations.md +73 -0
- data/lessons/02-local-development.md +121 -0
- data/lessons/03-embedded-rubydb.md +99 -0
- data/lessons/04-rails-complex-apps.md +138 -0
- data/lessons/05-rubydb-production-server.md +237 -0
- data/lessons/06-postgresql-massive-apps.md +96 -0
- data/lessons/07-hybrid-microservices.md +179 -0
- data/lessons/08-migrations-backups-recovery.md +86 -0
- data/lessons/09-observability-security-scale.md +87 -0
- data/lessons/10-release-readiness.md +192 -0
- data/lessons/11-community-adapter.md +323 -0
- data/lessons/12-rails-ecommerce-pressure.md +263 -0
- data/lib/rubydb/accelerator/client.rb +451 -0
- data/lib/rubydb/accelerator/error.rb +22 -0
- data/lib/rubydb/accelerator/manager.rb +606 -0
- data/lib/rubydb/accelerator.rb +13 -0
- data/lib/rubydb/backup/archive.rb +332 -334
- data/lib/rubydb/backup/backup.rb +400 -401
- data/lib/rubydb/backup/incremental.rb +349 -353
- data/lib/rubydb/backup/restore.rb +289 -290
- data/lib/rubydb/backup/snapshot.rb +265 -267
- data/lib/rubydb/backup/verification.rb +276 -279
- data/lib/rubydb/branching/branch.rb +181 -181
- data/lib/rubydb/branching/branch_manager.rb +307 -311
- data/lib/rubydb/branching/branch_metadata.rb +140 -140
- data/lib/rubydb/branching/checkout.rb +165 -166
- data/lib/rubydb/branching/copy_on_write.rb +272 -272
- data/lib/rubydb/branching/diff.rb +137 -138
- data/lib/rubydb/branching/merge.rb +282 -285
- data/lib/rubydb/build_info.rb +15 -15
- data/lib/rubydb/catalog/catalog.rb +391 -391
- data/lib/rubydb/catalog/column.rb +112 -112
- data/lib/rubydb/catalog/constraint.rb +180 -180
- data/lib/rubydb/catalog/database.rb +184 -184
- data/lib/rubydb/catalog/index.rb +97 -97
- data/lib/rubydb/catalog/schema.rb +103 -103
- data/lib/rubydb/catalog/sequence.rb +90 -90
- data/lib/rubydb/catalog/system_catalog.rb +698 -698
- data/lib/rubydb/catalog/table.rb +178 -178
- data/lib/rubydb/catalog/trigger.rb +102 -102
- data/lib/rubydb/catalog/view.rb +66 -66
- data/lib/rubydb/cli/application.rb +168 -163
- data/lib/rubydb/cli/commands/accelerator.rb +72 -0
- data/lib/rubydb/cli/commands/backup.rb +80 -81
- data/lib/rubydb/cli/commands/branch.rb +72 -72
- data/lib/rubydb/cli/commands/checkout.rb +54 -54
- data/lib/rubydb/cli/commands/create.rb +58 -58
- data/lib/rubydb/cli/commands/diff.rb +76 -77
- data/lib/rubydb/cli/commands/doctor.rb +77 -74
- data/lib/rubydb/cli/commands/drop.rb +57 -57
- data/lib/rubydb/cli/commands/init.rb +101 -102
- data/lib/rubydb/cli/commands/inspect.rb +95 -95
- data/lib/rubydb/cli/commands/merge.rb +63 -63
- data/lib/rubydb/cli/commands/migrate.rb +62 -62
- data/lib/rubydb/cli/commands/restart.rb +42 -39
- data/lib/rubydb/cli/commands/restore.rb +121 -121
- data/lib/rubydb/cli/commands/shell.rb +365 -365
- data/lib/rubydb/cli/commands/snapshot.rb +79 -79
- data/lib/rubydb/cli/commands/start.rb +88 -82
- data/lib/rubydb/cli/commands/status.rb +96 -92
- data/lib/rubydb/cli/commands/stop.rb +47 -47
- data/lib/rubydb/cli/commands/vacuum.rb +58 -58
- data/lib/rubydb/cli/formatter.rb +221 -221
- data/lib/rubydb/cli/output.rb +168 -168
- data/lib/rubydb/client/client.rb +309 -304
- data/lib/rubydb/client/connection.rb +429 -415
- data/lib/rubydb/client/connection_pool.rb +168 -168
- data/lib/rubydb/client/connection_url.rb +96 -96
- data/lib/rubydb/client/prepared_statement.rb +60 -60
- data/lib/rubydb/client/result.rb +127 -123
- data/lib/rubydb/client/statement.rb +52 -52
- data/lib/rubydb/client/transaction.rb +130 -130
- data/lib/rubydb/concurrency/concurrency.rb +19 -19
- data/lib/rubydb/concurrency/deadlock_detector.rb +148 -150
- data/lib/rubydb/concurrency/latch.rb +101 -101
- data/lib/rubydb/concurrency/lock_graph.rb +163 -165
- data/lib/rubydb/concurrency/mutex.rb +181 -183
- data/lib/rubydb/concurrency/rw_lock.rb +180 -180
- data/lib/rubydb/concurrency/scheduler.rb +248 -250
- data/lib/rubydb/concurrency/worker_pool.rb +145 -143
- data/lib/rubydb/configuration/config.rb +170 -170
- data/lib/rubydb/configuration/defaults.rb +191 -179
- data/lib/rubydb/configuration/environment.rb +152 -152
- data/lib/rubydb/configuration/parser.rb +185 -185
- data/lib/rubydb/configuration/validation.rb +228 -221
- data/lib/rubydb/constants.rb +74 -74
- data/lib/rubydb/constraints/check.rb +181 -181
- data/lib/rubydb/constraints/constraint.rb +101 -101
- data/lib/rubydb/constraints/foreign_key.rb +130 -130
- data/lib/rubydb/constraints/not_null.rb +64 -64
- data/lib/rubydb/constraints/primary_key.rb +99 -99
- data/lib/rubydb/constraints/unique.rb +106 -108
- data/lib/rubydb/constraints/validator.rb +349 -350
- data/lib/rubydb/errors/authentication_error.rb +10 -10
- data/lib/rubydb/errors/authorization_error.rb +23 -23
- data/lib/rubydb/errors/client_error.rb +10 -10
- data/lib/rubydb/errors/configuration_error.rb +10 -10
- data/lib/rubydb/errors/connection_error.rb +10 -10
- data/lib/rubydb/errors/constraint_error.rb +23 -23
- data/lib/rubydb/errors/corruption_error.rb +10 -10
- data/lib/rubydb/errors/database_error.rb +10 -10
- data/lib/rubydb/errors/error.rb +20 -20
- data/lib/rubydb/errors/execution_error.rb +10 -10
- data/lib/rubydb/errors/parser_error.rb +10 -10
- data/lib/rubydb/errors/recovery_error.rb +10 -10
- data/lib/rubydb/errors/replication_error.rb +10 -10
- data/lib/rubydb/errors/server_error.rb +6 -6
- data/lib/rubydb/errors/storage_error.rb +10 -10
- data/lib/rubydb/errors/transaction_error.rb +10 -10
- data/lib/rubydb/execution/accelerator_dispatch.rb +30 -0
- data/lib/rubydb/execution/aggregate_executor.rb +134 -138
- data/lib/rubydb/execution/cost_model.rb +72 -0
- data/lib/rubydb/execution/delete_executor.rb +110 -112
- data/lib/rubydb/execution/distinct_executor.rb +131 -135
- data/lib/rubydb/execution/executor.rb +1544 -1188
- data/lib/rubydb/execution/expression.rb +191 -193
- data/lib/rubydb/execution/index_scan.rb +142 -142
- data/lib/rubydb/execution/insert_executor.rb +215 -217
- data/lib/rubydb/execution/join_executor.rb +243 -249
- data/lib/rubydb/execution/limit_executor.rb +83 -85
- data/lib/rubydb/execution/operator_selection.rb +57 -0
- data/lib/rubydb/execution/optimizer.rb +227 -215
- data/lib/rubydb/execution/physical_plan.rb +47 -0
- data/lib/rubydb/execution/plan.rb +355 -353
- data/lib/rubydb/execution/planner.rb +508 -536
- data/lib/rubydb/execution/predicate.rb +235 -235
- data/lib/rubydb/execution/scan.rb +49 -49
- data/lib/rubydb/execution/sequential_scan.rb +63 -63
- data/lib/rubydb/execution/sort_executor.rb +194 -185
- data/lib/rubydb/execution/update_executor.rb +160 -162
- data/lib/rubydb/functions/aggregate.rb +70 -70
- data/lib/rubydb/functions/date_functions.rb +274 -278
- data/lib/rubydb/functions/function.rb +85 -85
- data/lib/rubydb/functions/json_functions.rb +231 -215
- data/lib/rubydb/functions/numeric_functions.rb +346 -346
- data/lib/rubydb/functions/scalar.rb +52 -52
- data/lib/rubydb/functions/string_functions.rb +383 -383
- data/lib/rubydb/functions/system_functions.rb +258 -246
- data/lib/rubydb/history/as_of.rb +238 -238
- data/lib/rubydb/history/change.rb +105 -105
- data/lib/rubydb/history/history.rb +131 -131
- data/lib/rubydb/history/history_manager.rb +228 -229
- data/lib/rubydb/history/temporal_query.rb +202 -202
- data/lib/rubydb/history/timeline.rb +144 -144
- data/lib/rubydb/indexes/btree.rb +215 -186
- data/lib/rubydb/indexes/btree_cursor.rb +258 -258
- data/lib/rubydb/indexes/btree_node.rb +384 -385
- data/lib/rubydb/indexes/hash_index.rb +150 -150
- data/lib/rubydb/indexes/index.rb +71 -71
- data/lib/rubydb/indexes/index_manager.rb +408 -406
- data/lib/rubydb/indexes/index_scan.rb +466 -470
- data/lib/rubydb/migrations/migration.rb +253 -254
- data/lib/rubydb/migrations/migration_lock.rb +146 -146
- data/lib/rubydb/migrations/migration_manager.rb +187 -176
- data/lib/rubydb/migrations/migration_version.rb +71 -71
- data/lib/rubydb/migrations/schema_diff.rb +211 -211
- data/lib/rubydb/migrations/schema_version.rb +64 -64
- data/lib/rubydb/monitoring/events.rb +155 -160
- data/lib/rubydb/monitoring/health.rb +216 -222
- data/lib/rubydb/monitoring/logger.rb +188 -193
- data/lib/rubydb/monitoring/metrics.rb +363 -359
- data/lib/rubydb/monitoring/performance.rb +176 -176
- data/lib/rubydb/monitoring/statistics.rb +168 -170
- data/lib/rubydb/mvcc/garbage_collector.rb +199 -199
- data/lib/rubydb/mvcc/mvcc.rb +16 -16
- data/lib/rubydb/mvcc/snapshot.rb +146 -147
- data/lib/rubydb/mvcc/vacuum.rb +180 -180
- data/lib/rubydb/mvcc/version.rb +106 -106
- data/lib/rubydb/mvcc/version_store.rb +396 -398
- data/lib/rubydb/mvcc/visibility.rb +107 -109
- data/lib/rubydb/protocol/capabilities.rb +125 -125
- data/lib/rubydb/protocol/decoder.rb +142 -145
- data/lib/rubydb/protocol/encoder.rb +131 -136
- data/lib/rubydb/protocol/handshake.rb +306 -305
- data/lib/rubydb/protocol/message.rb +121 -121
- data/lib/rubydb/protocol/parameter_binder.rb +101 -0
- data/lib/rubydb/protocol/protocol.rb +276 -277
- data/lib/rubydb/protocol/version.rb +54 -54
- data/lib/rubydb/rails/adapter.rb +245 -239
- data/lib/rubydb/rails/connection.rb +312 -314
- data/lib/rubydb/rails/database_statements.rb +122 -122
- data/lib/rubydb/rails/migration.rb +131 -131
- data/lib/rubydb/rails/quoting.rb +109 -109
- data/lib/rubydb/rails/result.rb +117 -117
- data/lib/rubydb/rails/schema_statements.rb +339 -339
- data/lib/rubydb/rails/transaction.rb +105 -105
- data/lib/rubydb/rails/type.rb +126 -126
- data/lib/rubydb/recovery/checkpoint.rb +261 -257
- data/lib/rubydb/recovery/consistency.rb +457 -467
- data/lib/rubydb/recovery/corruption_detector.rb +5 -5
- data/lib/rubydb/recovery/crash_recovery.rb +381 -387
- data/lib/rubydb/recovery/recovery_manager.rb +204 -206
- data/lib/rubydb/recovery/redo.rb +235 -237
- data/lib/rubydb/recovery/undo.rb +204 -206
- data/lib/rubydb/replication/failover.rb +5 -5
- data/lib/rubydb/replication/fencing.rb +63 -63
- data/lib/rubydb/replication/primary.rb +461 -450
- data/lib/rubydb/replication/replica.rb +382 -384
- data/lib/rubydb/replication/replication_log.rb +194 -200
- data/lib/rubydb/replication/replication_manager.rb +307 -308
- data/lib/rubydb/replication/replication_slot.rb +293 -295
- data/lib/rubydb/replication/replication_stream.rb +198 -201
- data/lib/rubydb/rubydb.rb +570 -560
- data/lib/rubydb/security/access_control.rb +252 -254
- data/lib/rubydb/security/audit_log.rb +209 -213
- data/lib/rubydb/security/authentication.rb +302 -302
- data/lib/rubydb/security/authorization.rb +282 -282
- data/lib/rubydb/security/credentials.rb +192 -196
- data/lib/rubydb/security/password.rb +205 -215
- data/lib/rubydb/security/permissions.rb +74 -74
- data/lib/rubydb/security/role.rb +99 -101
- data/lib/rubydb/security/user.rb +86 -86
- data/lib/rubydb/server/connection.rb +383 -366
- data/lib/rubydb/server/connection_pool.rb +193 -193
- data/lib/rubydb/server/lifecycle.rb +227 -228
- data/lib/rubydb/server/listener.rb +139 -136
- data/lib/rubydb/server/request_handler.rb +277 -276
- data/lib/rubydb/server/server.rb +363 -364
- data/lib/rubydb/server/session.rb +416 -369
- data/lib/rubydb/server/worker.rb +206 -210
- data/lib/rubydb/server/worker_pool.rb +168 -168
- data/lib/rubydb/sql/ast/alter_table.rb +169 -169
- data/lib/rubydb/sql/ast/begin_transaction.rb +47 -47
- data/lib/rubydb/sql/ast/commit.rb +37 -37
- data/lib/rubydb/sql/ast/constraint.rb +92 -83
- data/lib/rubydb/sql/ast/create_database.rb +41 -41
- data/lib/rubydb/sql/ast/create_index.rb +61 -61
- data/lib/rubydb/sql/ast/create_schema.rb +52 -52
- data/lib/rubydb/sql/ast/create_table.rb +187 -187
- data/lib/rubydb/sql/ast/delete.rb +54 -54
- data/lib/rubydb/sql/ast/drop_database.rb +41 -41
- data/lib/rubydb/sql/ast/drop_index.rb +41 -41
- data/lib/rubydb/sql/ast/drop_schema.rb +49 -49
- data/lib/rubydb/sql/ast/drop_table.rb +49 -49
- data/lib/rubydb/sql/ast/explain.rb +64 -64
- data/lib/rubydb/sql/ast/expression.rb +617 -604
- data/lib/rubydb/sql/ast/insert.rb +66 -66
- data/lib/rubydb/sql/ast/node.rb +42 -42
- data/lib/rubydb/sql/ast/rollback.rb +63 -63
- data/lib/rubydb/sql/ast/savepoint.rb +59 -59
- data/lib/rubydb/sql/ast/select.rb +88 -88
- data/lib/rubydb/sql/ast/set_operation.rb +22 -20
- data/lib/rubydb/sql/ast/trigger.rb +35 -29
- data/lib/rubydb/sql/ast/update.rb +88 -88
- data/lib/rubydb/sql/ast/vacuum.rb +19 -19
- data/lib/rubydb/sql/ast/view.rb +38 -32
- data/lib/rubydb/sql/ast/with.rb +32 -32
- data/lib/rubydb/sql/grammar.rb +86 -86
- data/lib/rubydb/sql/keywords.rb +156 -156
- data/lib/rubydb/sql/lexer.rb +209 -214
- data/lib/rubydb/sql/operators.rb +100 -100
- data/lib/rubydb/sql/parser.rb +1167 -1170
- data/lib/rubydb/sql/planner/analyzer.rb +283 -302
- data/lib/rubydb/sql/planner/binder.rb +537 -550
- data/lib/rubydb/sql/planner/type_checker.rb +427 -431
- data/lib/rubydb/sql/token.rb +210 -210
- data/lib/rubydb/storage/buffer_frame.rb +44 -44
- data/lib/rubydb/storage/buffer_pool.rb +155 -155
- data/lib/rubydb/storage/database_lock.rb +74 -74
- data/lib/rubydb/storage/deserializer.rb +332 -342
- data/lib/rubydb/storage/engine.rb +2409 -2330
- data/lib/rubydb/storage/file_manager.rb +191 -187
- data/lib/rubydb/storage/free_space_map.rb +79 -81
- data/lib/rubydb/storage/page.rb +92 -94
- data/lib/rubydb/storage/page_allocator.rb +852 -855
- data/lib/rubydb/storage/page_header.rb +63 -67
- data/lib/rubydb/storage/page_manager.rb +127 -131
- data/lib/rubydb/storage/record.rb +58 -58
- data/lib/rubydb/storage/row.rb +78 -78
- data/lib/rubydb/storage/serializer.rb +51 -51
- data/lib/rubydb/storage/snapshot_reader.rb +167 -0
- data/lib/rubydb/storage/storage_layout.rb +151 -151
- data/lib/rubydb/storage/storage_manager.rb +114 -114
- data/lib/rubydb/storage/tuple.rb +458 -461
- data/lib/rubydb/storage/visibility_map.rb +964 -973
- data/lib/rubydb/transactions/commit_manager.rb +219 -220
- data/lib/rubydb/transactions/isolation.rb +98 -98
- data/lib/rubydb/transactions/lock.rb +76 -76
- data/lib/rubydb/transactions/lock_manager.rb +359 -362
- data/lib/rubydb/transactions/savepoint.rb +142 -143
- data/lib/rubydb/transactions/transaction.rb +214 -215
- data/lib/rubydb/transactions/transaction_id.rb +84 -84
- data/lib/rubydb/transactions/transaction_log.rb +256 -257
- data/lib/rubydb/transactions/transaction_manager.rb +434 -435
- data/lib/rubydb/types/bigint.rb +36 -36
- data/lib/rubydb/types/blob.rb +37 -37
- data/lib/rubydb/types/boolean.rb +34 -34
- data/lib/rubydb/types/date.rb +39 -39
- data/lib/rubydb/types/decimal.rb +48 -48
- data/lib/rubydb/types/float.rb +34 -34
- data/lib/rubydb/types/integer.rb +36 -36
- data/lib/rubydb/types/json.rb +41 -41
- data/lib/rubydb/types/null.rb +34 -34
- data/lib/rubydb/types/smallint.rb +36 -36
- data/lib/rubydb/types/text.rb +37 -37
- data/lib/rubydb/types/time.rb +46 -46
- data/lib/rubydb/types/timestamp.rb +39 -39
- data/lib/rubydb/types/type.rb +119 -119
- data/lib/rubydb/types/uuid.rb +47 -47
- data/lib/rubydb/types/varchar.rb +37 -37
- data/lib/rubydb/version.rb +32 -32
- data/lib/rubydb/wal/archive.rb +207 -193
- data/lib/rubydb/wal/checkpoint.rb +181 -183
- data/lib/rubydb/wal/lsn.rb +94 -94
- data/lib/rubydb/wal/reader.rb +259 -260
- data/lib/rubydb/wal/record.rb +105 -105
- data/lib/rubydb/wal/segment.rb +193 -193
- data/lib/rubydb/wal/wal.rb +481 -452
- data/lib/rubydb/wal/writer.rb +236 -236
- data/lib/rubydb.rb +7 -7
- data/packaging/docker/docker-compose.failover.yml +43 -43
- data/packaging/homebrew/rubydb.rb +19 -19
- data/rubydb.gemspec +70 -57
- data/scripts/benchmark +7 -7
- data/scripts/build_accelerator +49 -0
- data/scripts/durability_drill +37 -37
- data/scripts/fuzz +63 -63
- data/scripts/release +77 -42
- data/scripts/release_check +43 -43
- data/scripts/replication_failover_drill +268 -250
- data/scripts/replication_network_failover_drill +287 -255
- data/scripts/restore_drill +45 -45
- data/scripts/security +45 -0
- metadata +102 -1
data/lib/rubydb/types/bigint.rb
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# 64-bit signed integer
|
|
6
|
-
class BigInt < Type
|
|
7
|
-
RANGE = (-9_223_372_036_854_775_808..9_223_372_036_854_775_807)
|
|
8
|
-
SIZE = 8
|
|
9
|
-
|
|
10
|
-
def initialize
|
|
11
|
-
super(:bigint, size: SIZE)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def serialize(value)
|
|
15
|
-
validate(value)
|
|
16
|
-
[value.to_i].pack("q>") # Big-endian 64-bit signed
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def deserialize(bytes)
|
|
20
|
-
return nil if bytes.nil? || bytes.empty?
|
|
21
|
-
bytes.
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def validate(value)
|
|
25
|
-
return true if value.nil?
|
|
26
|
-
raise ConstraintError, "Invalid bigint: #{value}" unless value.is_a?(::Integer)
|
|
27
|
-
raise ConstraintError, "BigInt out of range: #{value}" unless RANGE.include?(value)
|
|
28
|
-
true
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def default
|
|
32
|
-
0
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# 64-bit signed integer
|
|
6
|
+
class BigInt < Type
|
|
7
|
+
RANGE = (-9_223_372_036_854_775_808..9_223_372_036_854_775_807)
|
|
8
|
+
SIZE = 8
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
super(:bigint, size: SIZE)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serialize(value)
|
|
15
|
+
validate(value)
|
|
16
|
+
[value.to_i].pack("q>") # Big-endian 64-bit signed
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def deserialize(bytes)
|
|
20
|
+
return nil if bytes.nil? || bytes.empty?
|
|
21
|
+
bytes.unpack1("q>")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate(value)
|
|
25
|
+
return true if value.nil?
|
|
26
|
+
raise ConstraintError, "Invalid bigint: #{value}" unless value.is_a?(::Integer)
|
|
27
|
+
raise ConstraintError, "BigInt out of range: #{value}" unless RANGE.include?(value)
|
|
28
|
+
true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def default
|
|
32
|
+
0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/rubydb/types/blob.rb
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# Binary large object (arbitrary binary data)
|
|
6
|
-
class Blob < Type
|
|
7
|
-
def initialize
|
|
8
|
-
super(:blob)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def serialize(value)
|
|
12
|
-
validate(value)
|
|
13
|
-
return "".b if value.nil?
|
|
14
|
-
value.is_a?(String) ? value.b : value.to_s.b
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def deserialize(bytes)
|
|
18
|
-
return nil if bytes.nil? || bytes.empty?
|
|
19
|
-
bytes.b
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def validate(value)
|
|
23
|
-
return true if value.nil?
|
|
24
|
-
raise ConstraintError, "Invalid blob: #{value}" unless value.respond_to?(:to_s)
|
|
25
|
-
true
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def default
|
|
29
|
-
"".b
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def storage_size
|
|
33
|
-
nil # Variable length
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# Binary large object (arbitrary binary data)
|
|
6
|
+
class Blob < Type
|
|
7
|
+
def initialize
|
|
8
|
+
super(:blob)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def serialize(value)
|
|
12
|
+
validate(value)
|
|
13
|
+
return "".b if value.nil?
|
|
14
|
+
value.is_a?(String) ? value.b : value.to_s.b
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def deserialize(bytes)
|
|
18
|
+
return nil if bytes.nil? || bytes.empty?
|
|
19
|
+
bytes.b
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate(value)
|
|
23
|
+
return true if value.nil?
|
|
24
|
+
raise ConstraintError, "Invalid blob: #{value}" unless value.respond_to?(:to_s)
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def default
|
|
29
|
+
"".b
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def storage_size
|
|
33
|
+
nil # Variable length
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/rubydb/types/boolean.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# Boolean type (true/false)
|
|
6
|
-
class Boolean < Type
|
|
7
|
-
SIZE = 1
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
super(:boolean, size: SIZE)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def serialize(value)
|
|
14
|
-
validate(value)
|
|
15
|
-
value ? "\x01".b : "\x00".b
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def deserialize(bytes)
|
|
19
|
-
return nil if bytes.nil? || bytes.empty?
|
|
20
|
-
bytes.
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def validate(value)
|
|
24
|
-
return true if value.nil?
|
|
25
|
-
raise ConstraintError, "Invalid boolean: #{value}" unless [true, false].include?(value)
|
|
26
|
-
true
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def default
|
|
30
|
-
false
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# Boolean type (true/false)
|
|
6
|
+
class Boolean < Type
|
|
7
|
+
SIZE = 1
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super(:boolean, size: SIZE)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def serialize(value)
|
|
14
|
+
validate(value)
|
|
15
|
+
value ? "\x01".b : "\x00".b
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def deserialize(bytes)
|
|
19
|
+
return nil if bytes.nil? || bytes.empty?
|
|
20
|
+
bytes.unpack1("C") == 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate(value)
|
|
24
|
+
return true if value.nil?
|
|
25
|
+
raise ConstraintError, "Invalid boolean: #{value}" unless [true, false].include?(value)
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def default
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/rubydb/types/date.rb
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "date"
|
|
4
|
-
|
|
5
|
-
module RubyDB
|
|
6
|
-
module Types
|
|
7
|
-
# Date type (year, month, day)
|
|
8
|
-
class Date < Type
|
|
9
|
-
SIZE = 4 # Days since epoch (stored as integer)
|
|
10
|
-
|
|
11
|
-
def initialize
|
|
12
|
-
super(:date, size: SIZE)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def serialize(value)
|
|
16
|
-
validate(value)
|
|
17
|
-
return "\x00" * SIZE if value.nil?
|
|
18
|
-
days = value - Date.new(1970, 1, 1)
|
|
19
|
-
[days.to_i].pack("l>")
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def deserialize(bytes)
|
|
23
|
-
return nil if bytes.nil? || bytes.empty?
|
|
24
|
-
days = bytes.
|
|
25
|
-
Date.new(1970, 1, 1) + days
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def validate(value)
|
|
29
|
-
return true if value.nil?
|
|
30
|
-
raise ConstraintError, "Invalid date: #{value}" unless value.is_a?(::Date) || value.is_a?(::DateTime)
|
|
31
|
-
true
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def default
|
|
35
|
-
Date.today
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
|
|
5
|
+
module RubyDB
|
|
6
|
+
module Types
|
|
7
|
+
# Date type (year, month, day)
|
|
8
|
+
class Date < Type
|
|
9
|
+
SIZE = 4 # Days since epoch (stored as integer)
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
super(:date, size: SIZE)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def serialize(value)
|
|
16
|
+
validate(value)
|
|
17
|
+
return "\x00" * SIZE if value.nil?
|
|
18
|
+
days = value - Date.new(1970, 1, 1)
|
|
19
|
+
[days.to_i].pack("l>")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def deserialize(bytes)
|
|
23
|
+
return nil if bytes.nil? || bytes.empty?
|
|
24
|
+
days = bytes.unpack1("l>")
|
|
25
|
+
Date.new(1970, 1, 1) + days
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def validate(value)
|
|
29
|
+
return true if value.nil?
|
|
30
|
+
raise ConstraintError, "Invalid date: #{value}" unless value.is_a?(::Date) || value.is_a?(::DateTime)
|
|
31
|
+
true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def default
|
|
35
|
+
Date.today
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/rubydb/types/decimal.rb
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bigdecimal"
|
|
4
|
-
|
|
5
|
-
module RubyDB
|
|
6
|
-
module Types
|
|
7
|
-
# Arbitrary precision decimal
|
|
8
|
-
class Decimal < Type
|
|
9
|
-
attr_reader :precision, :scale
|
|
10
|
-
|
|
11
|
-
def initialize(precision: 10, scale: 2)
|
|
12
|
-
super(:decimal, precision: precision, scale: scale)
|
|
13
|
-
@precision = precision
|
|
14
|
-
@scale = scale
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def serialize(value)
|
|
18
|
-
validate(value)
|
|
19
|
-
bd = value.is_a?(BigDecimal) ? value : BigDecimal(value.to_s)
|
|
20
|
-
bd.to_s("F").encode("UTF-8")
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def deserialize(bytes)
|
|
24
|
-
return nil if bytes.nil? || bytes.empty?
|
|
25
|
-
str = bytes.force_encoding("UTF-8")
|
|
26
|
-
BigDecimal(str)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def validate(value)
|
|
30
|
-
return true if value.nil?
|
|
31
|
-
bd = value.is_a?(BigDecimal) ? value : BigDecimal(value.to_s)
|
|
32
|
-
raise ConstraintError, "Invalid decimal: #{value}" unless bd
|
|
33
|
-
true
|
|
34
|
-
rescue ArgumentError, TypeError
|
|
35
|
-
raise ConstraintError, "Invalid decimal: #{value}"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def default
|
|
39
|
-
BigDecimal("0")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def storage_size
|
|
43
|
-
# Variable length, stored as string
|
|
44
|
-
nil
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
module RubyDB
|
|
6
|
+
module Types
|
|
7
|
+
# Arbitrary precision decimal
|
|
8
|
+
class Decimal < Type
|
|
9
|
+
attr_reader :precision, :scale
|
|
10
|
+
|
|
11
|
+
def initialize(precision: 10, scale: 2)
|
|
12
|
+
super(:decimal, precision: precision, scale: scale)
|
|
13
|
+
@precision = precision
|
|
14
|
+
@scale = scale
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def serialize(value)
|
|
18
|
+
validate(value)
|
|
19
|
+
bd = value.is_a?(BigDecimal) ? value : BigDecimal(value.to_s)
|
|
20
|
+
bd.to_s("F").encode("UTF-8")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def deserialize(bytes)
|
|
24
|
+
return nil if bytes.nil? || bytes.empty?
|
|
25
|
+
str = bytes.force_encoding("UTF-8")
|
|
26
|
+
BigDecimal(str)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate(value)
|
|
30
|
+
return true if value.nil?
|
|
31
|
+
bd = value.is_a?(BigDecimal) ? value : BigDecimal(value.to_s)
|
|
32
|
+
raise ConstraintError, "Invalid decimal: #{value}" unless bd
|
|
33
|
+
true
|
|
34
|
+
rescue ArgumentError, TypeError
|
|
35
|
+
raise ConstraintError, "Invalid decimal: #{value}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def default
|
|
39
|
+
BigDecimal("0")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def storage_size
|
|
43
|
+
# Variable length, stored as string
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/rubydb/types/float.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# 64-bit floating point (Double precision)
|
|
6
|
-
class Float < Type
|
|
7
|
-
SIZE = 8
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
super(:float, size: SIZE)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def serialize(value)
|
|
14
|
-
validate(value)
|
|
15
|
-
[value.to_f].pack("E") # Big-endian double
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def deserialize(bytes)
|
|
19
|
-
return nil if bytes.nil? || bytes.empty?
|
|
20
|
-
bytes.
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def validate(value)
|
|
24
|
-
return true if value.nil?
|
|
25
|
-
raise ConstraintError, "Invalid float: #{value}" unless value.is_a?(::Numeric)
|
|
26
|
-
true
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def default
|
|
30
|
-
0.0
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# 64-bit floating point (Double precision)
|
|
6
|
+
class Float < Type
|
|
7
|
+
SIZE = 8
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super(:float, size: SIZE)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def serialize(value)
|
|
14
|
+
validate(value)
|
|
15
|
+
[value.to_f].pack("E") # Big-endian double
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def deserialize(bytes)
|
|
19
|
+
return nil if bytes.nil? || bytes.empty?
|
|
20
|
+
bytes.unpack1("E")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate(value)
|
|
24
|
+
return true if value.nil?
|
|
25
|
+
raise ConstraintError, "Invalid float: #{value}" unless value.is_a?(::Numeric)
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def default
|
|
30
|
+
0.0
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/rubydb/types/integer.rb
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# 32-bit signed integer
|
|
6
|
-
class Integer < Type
|
|
7
|
-
RANGE = (-2_147_483_648..2_147_483_647)
|
|
8
|
-
SIZE = 4
|
|
9
|
-
|
|
10
|
-
def initialize
|
|
11
|
-
super(:integer, size: SIZE)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def serialize(value)
|
|
15
|
-
validate(value)
|
|
16
|
-
[value.to_i].pack("l>") # Big-endian 32-bit signed
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def deserialize(bytes)
|
|
20
|
-
return nil if bytes.nil? || bytes.empty?
|
|
21
|
-
bytes.
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def validate(value)
|
|
25
|
-
return true if value.nil?
|
|
26
|
-
raise ConstraintError, "Invalid integer: #{value}" unless value.is_a?(::Integer)
|
|
27
|
-
raise ConstraintError, "Integer out of range: #{value}" unless RANGE.include?(value)
|
|
28
|
-
true
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def default
|
|
32
|
-
0
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# 32-bit signed integer
|
|
6
|
+
class Integer < Type
|
|
7
|
+
RANGE = (-2_147_483_648..2_147_483_647)
|
|
8
|
+
SIZE = 4
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
super(:integer, size: SIZE)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serialize(value)
|
|
15
|
+
validate(value)
|
|
16
|
+
[value.to_i].pack("l>") # Big-endian 32-bit signed
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def deserialize(bytes)
|
|
20
|
+
return nil if bytes.nil? || bytes.empty?
|
|
21
|
+
bytes.unpack1("l>")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate(value)
|
|
25
|
+
return true if value.nil?
|
|
26
|
+
raise ConstraintError, "Invalid integer: #{value}" unless value.is_a?(::Integer)
|
|
27
|
+
raise ConstraintError, "Integer out of range: #{value}" unless RANGE.include?(value)
|
|
28
|
+
true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def default
|
|
32
|
+
0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/rubydb/types/json.rb
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
|
|
5
|
-
module RubyDB
|
|
6
|
-
module Types
|
|
7
|
-
# JSON type (stores JSON data)
|
|
8
|
-
class Json < Type
|
|
9
|
-
def initialize
|
|
10
|
-
super(:json)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def serialize(value)
|
|
14
|
-
validate(value)
|
|
15
|
-
return "null".encode("UTF-8") if value.nil?
|
|
16
|
-
JSON.generate(value)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def deserialize(bytes)
|
|
20
|
-
return nil if bytes.nil? || bytes.empty?
|
|
21
|
-
JSON.parse(bytes.force_encoding("UTF-8"))
|
|
22
|
-
rescue JSON::ParserError
|
|
23
|
-
nil
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def validate(value)
|
|
27
|
-
return true if value.nil?
|
|
28
|
-
raise ConstraintError, "Invalid JSON: #{value}" unless value.is_a?(Hash) || value.is_a?(Array)
|
|
29
|
-
true
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def default
|
|
33
|
-
{}
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def storage_size
|
|
37
|
-
nil # Variable length
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module RubyDB
|
|
6
|
+
module Types
|
|
7
|
+
# JSON type (stores JSON data)
|
|
8
|
+
class Json < Type
|
|
9
|
+
def initialize
|
|
10
|
+
super(:json)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def serialize(value)
|
|
14
|
+
validate(value)
|
|
15
|
+
return "null".encode("UTF-8") if value.nil?
|
|
16
|
+
JSON.generate(value)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def deserialize(bytes)
|
|
20
|
+
return nil if bytes.nil? || bytes.empty?
|
|
21
|
+
JSON.parse(bytes.force_encoding("UTF-8"))
|
|
22
|
+
rescue JSON::ParserError
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def validate(value)
|
|
27
|
+
return true if value.nil?
|
|
28
|
+
raise ConstraintError, "Invalid JSON: #{value}" unless value.is_a?(Hash) || value.is_a?(Array)
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def default
|
|
33
|
+
{}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def storage_size
|
|
37
|
+
nil # Variable length
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/rubydb/types/null.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyDB
|
|
4
|
-
module Types
|
|
5
|
-
# NULL type (represents absence of value)
|
|
6
|
-
class Null < Type
|
|
7
|
-
SIZE = 0
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
super(:null, size: SIZE)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def serialize(value)
|
|
14
|
-
""
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def deserialize(bytes)
|
|
18
|
-
nil
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def validate(value)
|
|
22
|
-
true # Always valid
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def default
|
|
26
|
-
nil
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def storage_size
|
|
30
|
-
0
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyDB
|
|
4
|
+
module Types
|
|
5
|
+
# NULL type (represents absence of value)
|
|
6
|
+
class Null < Type
|
|
7
|
+
SIZE = 0
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super(:null, size: SIZE)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def serialize(value)
|
|
14
|
+
""
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def deserialize(bytes)
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate(value)
|
|
22
|
+
true # Always valid
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def default
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def storage_size
|
|
30
|
+
0
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|