rubydb 0.1.4 → 0.1.5
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 +12 -5
- data/.rubocop.yml +50 -44
- data/.standard.yml +9 -14
- data/ARCHITECTURE.md +21 -21
- data/CHANGELOG.md +43 -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 +249 -162
- data/ROADMAP.md +27 -27
- data/Rakefile +71 -71
- data/SECURITY.md +54 -54
- data/SUPPORT.md +14 -14
- data/adapters/activerecord/Gemfile +11 -11
- data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +873 -879
- data/adapters/activerecord/rubydb-activerecord.gemspec +20 -20
- 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 +75 -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/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 +275 -275
- data/docs/contributing/architecture.md +9 -9
- data/docs/contributing/benchmarking.md +14 -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 +17 -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 +94 -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 +125 -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 +163 -163
- 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 +74 -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 +302 -304
- data/lib/rubydb/client/connection.rb +414 -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 +123 -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 +179 -179
- data/lib/rubydb/configuration/environment.rb +152 -152
- data/lib/rubydb/configuration/parser.rb +185 -185
- data/lib/rubydb/configuration/validation.rb +221 -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/aggregate_executor.rb +134 -138
- data/lib/rubydb/execution/delete_executor.rb +110 -112
- data/lib/rubydb/execution/distinct_executor.rb +131 -135
- data/lib/rubydb/execution/executor.rb +1182 -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/optimizer.rb +227 -215
- data/lib/rubydb/execution/plan.rb +355 -353
- data/lib/rubydb/execution/planner.rb +542 -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 +180 -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 +186 -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 +564 -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 +371 -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 +2347 -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/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 +190 -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 +480 -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 +60 -57
- data/scripts/benchmark +7 -7
- data/scripts/durability_drill +37 -37
- data/scripts/fuzz +63 -63
- data/scripts/release +45 -40
- 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 +54 -1
data/README.md
CHANGED
|
@@ -1,162 +1,249 @@
|
|
|
1
|
-
# RubyDB
|
|
2
|
-
|
|
3
|
-
RubyDB is a Ruby-native relational database with an embedded engine, a
|
|
4
|
-
client/server mode, a Ruby client, and an ActiveRecord adapter.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
1
|
+
# RubyDB
|
|
2
|
+
|
|
3
|
+
RubyDB is a Ruby-native relational database with an embedded engine, a
|
|
4
|
+
client/server mode, a Ruby client, and an ActiveRecord adapter.
|
|
5
|
+
|
|
6
|
+
**Author:** Aldane Hutchinson
|
|
7
|
+
|
|
8
|
+
> **Status: alpha.** RubyDB is suitable for experimentation, development,
|
|
9
|
+
> controlled embedded workloads, and production microservices that stay within
|
|
10
|
+
> the documented and tested feature set. RubyDB can be used in both development
|
|
11
|
+
> and production, but each production workload must pass its own query,
|
|
12
|
+
> concurrency, backup, restore, security, and operational validation. It
|
|
13
|
+
> provides a tested common SQLite-style profile, but is not a drop-in
|
|
14
|
+
> replacement for PostgreSQL, MySQL, or SQLite.
|
|
15
|
+
|
|
16
|
+
## Recommended database roles
|
|
17
|
+
|
|
18
|
+
Use RubyDB when you want a Ruby-native database for local development, tests,
|
|
19
|
+
internal tools, or an independently owned microservice with a bounded workload.
|
|
20
|
+
Use embedded mode when one Ruby process owns the database file. Use RubyDB
|
|
21
|
+
server/client mode when multiple application processes connect to one service.
|
|
22
|
+
|
|
23
|
+
Use PostgreSQL as the default system of record for massive applications,
|
|
24
|
+
high-concurrency public products, large shared Rails applications, advanced
|
|
25
|
+
PostgreSQL SQL/extensions, and workloads requiring a mature managed database
|
|
26
|
+
ecosystem. A common production architecture is PostgreSQL for the main app and
|
|
27
|
+
RubyDB for smaller, independently operated microservices.
|
|
28
|
+
|
|
29
|
+
## What works today
|
|
30
|
+
|
|
31
|
+
The repository contains implementation and automated coverage for:
|
|
32
|
+
|
|
33
|
+
- SQL tables, CRUD, joins, grouping and aggregates, ordering, transactions,
|
|
34
|
+
savepoints, conflict handling, and documented maintenance statements
|
|
35
|
+
- typed values, primary/foreign keys, unique and check constraints, and B-tree
|
|
36
|
+
indexes
|
|
37
|
+
- durable storage, WAL-backed commits, recovery, snapshots, branching, and
|
|
38
|
+
MVCC paths
|
|
39
|
+
- Ruby API, client/server protocol, connection pooling, configuration, and
|
|
40
|
+
operational tooling
|
|
41
|
+
- ActiveRecord integration, Rails migrations, and a runnable Rails example
|
|
42
|
+
|
|
43
|
+
These features are not a guarantee of compatibility with every application.
|
|
44
|
+
Run the test suite and validate your own schema, queries, workload, backup,
|
|
45
|
+
restore, and failure scenarios before using RubyDB for important data.
|
|
46
|
+
|
|
47
|
+
## Why “complete PostgreSQL/MySQL/SQLite compatibility” matters
|
|
48
|
+
|
|
49
|
+
That requirement is only necessary when RubyDB is intended to be a drop-in
|
|
50
|
+
replacement for an existing application using one of those databases.
|
|
51
|
+
|
|
52
|
+
It includes much more than accepting similar `SELECT` statements:
|
|
53
|
+
|
|
54
|
+
- dialect-specific SQL syntax, functions, operators, casts, and error behavior
|
|
55
|
+
- query semantics for joins, `NULL`, ordering, grouping, subqueries, CTEs,
|
|
56
|
+
unions, upserts, and window functions
|
|
57
|
+
- data types, indexes, constraints, generated values, and transaction behavior
|
|
58
|
+
- migration behavior and ActiveRecord adapter mappings
|
|
59
|
+
- client protocol, connection behavior, locking, limits, and operational tools
|
|
60
|
+
|
|
61
|
+
A new Ruby or Rails application does not need complete compatibility. It can
|
|
62
|
+
use RubyDB's documented SQL and adapter behavior directly. Compatibility is
|
|
63
|
+
needed to move an existing PostgreSQL, MySQL, or SQLite application without
|
|
64
|
+
rewriting queries and without discovering semantic differences in production.
|
|
65
|
+
|
|
66
|
+
RubyDB currently targets a documented RubyDB SQL subset plus tested Rails
|
|
67
|
+
operations. The compatibility documents describe the supported statements;
|
|
68
|
+
unsupported or unverified dialect features must not be assumed to work.
|
|
69
|
+
|
|
70
|
+
## Quick start
|
|
71
|
+
|
|
72
|
+
Install the prerelease gem:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
gem install rubydb --pre
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For local development from this repository:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
bundle install
|
|
82
|
+
bundle exec rspec
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Ruby usage
|
|
86
|
+
|
|
87
|
+
RubyDB can run embedded in a single owning process:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
require "rubydb"
|
|
91
|
+
|
|
92
|
+
engine = RubyDB::Storage::Engine.new("tmp/example.rdb")
|
|
93
|
+
engine.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
|
|
94
|
+
engine.execute("INSERT INTO users (name) VALUES ('Aldane')")
|
|
95
|
+
puts engine.execute("SELECT * FROM users").inspect
|
|
96
|
+
engine.close
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For multiple application processes, use RubyDB's server/client mode and point
|
|
100
|
+
clients at the managed server. Do not open the same embedded database path
|
|
101
|
+
from multiple independent processes. A regular Ruby application can use a
|
|
102
|
+
RubyDB connection URL supplied by its environment:
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
client = RubyDB::Client::Client.new(url: ENV.fetch("RUBYDB_URL"))
|
|
106
|
+
client.query("SELECT 1")
|
|
107
|
+
client.disconnect
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Use the `rubydb://` or TLS-enabled `rubydbs://` format documented in the Rails
|
|
111
|
+
configuration guide. RubyDB URLs are not PostgreSQL URLs.
|
|
112
|
+
|
|
113
|
+
## Copy-and-paste examples
|
|
114
|
+
|
|
115
|
+
### RubyDB for local development
|
|
116
|
+
|
|
117
|
+
This creates a durable local database in one owning Ruby process:
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
require "rubydb"
|
|
121
|
+
|
|
122
|
+
engine = RubyDB::Storage::Engine.new("tmp/development.rdb")
|
|
123
|
+
begin
|
|
124
|
+
engine.execute("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL)")
|
|
125
|
+
engine.execute("INSERT INTO notes (body) VALUES ('First note')")
|
|
126
|
+
puts engine.execute("SELECT id, body FROM notes ORDER BY id").inspect
|
|
127
|
+
ensure
|
|
128
|
+
engine.close
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Do not open the same embedded path from separate web and worker processes.
|
|
133
|
+
|
|
134
|
+
### RubyDB for a production microservice
|
|
135
|
+
|
|
136
|
+
Run one RubyDB server on persistent storage and inject a TLS URL into the
|
|
137
|
+
service:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
gem install rubydb -v 0.1.5
|
|
141
|
+
rubydb --config /etc/rubydb/production.yml --env production start
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
require "rubydb"
|
|
146
|
+
|
|
147
|
+
client = RubyDB::Client::Client.new(url: ENV.fetch("RUBYDB_URL"))
|
|
148
|
+
begin
|
|
149
|
+
puts client.query("SELECT 1").to_hash
|
|
150
|
+
ensure
|
|
151
|
+
client.disconnect
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Use a URL such as `rubydbs://user:URL_ENCODED_PASSWORD@db.internal:7432/app`
|
|
156
|
+
with TLS verification enabled. Store the complete URL in a secret manager and
|
|
157
|
+
keep the database service on a private network.
|
|
158
|
+
|
|
159
|
+
### PostgreSQL for a massive Rails application
|
|
160
|
+
|
|
161
|
+
Use the `pg` gem and a managed PostgreSQL connection string for the main
|
|
162
|
+
application:
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
# Gemfile
|
|
166
|
+
gem "pg"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
# config/database.yml
|
|
171
|
+
production:
|
|
172
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
|
173
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Set `DATABASE_URL` through the hosting provider’s secret settings, run
|
|
177
|
+
migrations once from a release job, and validate the application against the
|
|
178
|
+
same PostgreSQL major version used in production.
|
|
179
|
+
|
|
180
|
+
## Rails example
|
|
181
|
+
|
|
182
|
+
The small Rails 7.2 application in
|
|
183
|
+
[`examples/rails_app`](examples/rails_app) runs a real migration, model query,
|
|
184
|
+
and browser form through `rubydb-activerecord`.
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
cd examples/rails_app
|
|
188
|
+
bundle install
|
|
189
|
+
bundle exec ruby bin/rails db:migrate
|
|
190
|
+
bundle exec ruby bin/rails server -b 127.0.0.1 -p 3001
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Open <http://127.0.0.1:3001/>. The example uses an embedded database under
|
|
194
|
+
`tmp/`; set `RUBYDB_DATABASE` to choose another path. See the adapter and Rails
|
|
195
|
+
documentation for network configuration, migrations, production deployment,
|
|
196
|
+
backups, restore drills, and monitoring.
|
|
197
|
+
|
|
198
|
+
For an even smaller end-to-end smoke test, see the tiny GitHub-style app in
|
|
199
|
+
[`examples/github_clone`](examples/github_clone). It covers repositories,
|
|
200
|
+
issues, commits, Rails associations, foreign keys, indexes, seed data, and a
|
|
201
|
+
browser page backed by RubyDB.
|
|
202
|
+
|
|
203
|
+
## Compatibility policy
|
|
204
|
+
|
|
205
|
+
RubyDB does not claim complete PostgreSQL, MySQL, or SQLite compatibility until
|
|
206
|
+
each compatibility area has both an implementation and repeatable validation.
|
|
207
|
+
The project must validate at least:
|
|
208
|
+
|
|
209
|
+
1. parser and execution behavior for the documented dialect surface
|
|
210
|
+
2. type, constraint, transaction, locking, and error semantics
|
|
211
|
+
3. ActiveRecord queries, joins, eager loading, associations, and migrations
|
|
212
|
+
4. sustained concurrency, cancellation, recovery, backup/restore, and failover
|
|
213
|
+
5. supported Ruby, Rails, operating-system, and client/server combinations
|
|
214
|
+
|
|
215
|
+
Until then, compatibility should be treated as feature-specific, not implied
|
|
216
|
+
by the presence of an adapter.
|
|
217
|
+
|
|
218
|
+
## Documentation
|
|
219
|
+
|
|
220
|
+
- [Documentation index](docs/README.md)
|
|
221
|
+
- [Ten-lesson production journey](lessons/01-foundations.md)
|
|
222
|
+
- [Developer guide](docs/developer-guide.md)
|
|
223
|
+
- [Troubleshooting guide](docs/troubleshooting.md)
|
|
224
|
+
- [Debugging playbook](docs/debugging.md)
|
|
225
|
+
- [Production operations guide](docs/operations/production-guide.md)
|
|
226
|
+
- [Lessons learned](docs/lessons-learned.md)
|
|
227
|
+
- [Getting started](docs/getting-started/quickstart.md)
|
|
228
|
+
- [Local development to production](docs/getting-started/local-to-production.md)
|
|
229
|
+
- [SQL compatibility](docs/sql/compatibility.md)
|
|
230
|
+
- [SQL compatibility guide](docs/sql/compatibility-guide.md)
|
|
231
|
+
- [SQLite compatibility profile](docs/sql/sqlite-compatibility.md)
|
|
232
|
+
- [SQL syntax](docs/sql/syntax.md)
|
|
233
|
+
- [Rails installation](docs/rails/installation.md)
|
|
234
|
+
- [Rails production guidance](docs/rails/production.md)
|
|
235
|
+
- [Rails compatibility guide](docs/rails/compatibility-guide.md)
|
|
236
|
+
- [Python adapter](adapters/python/README.md)
|
|
237
|
+
- [Production readiness](docs/production-readiness.md)
|
|
238
|
+
- [Operations and workload testing](docs/operations/workload-testing.md)
|
|
239
|
+
- [Production runbook](docs/operations/production-runbook.md)
|
|
240
|
+
- [CLI guide](docs/cli.md)
|
|
241
|
+
- [CLI cheat sheet](docs/cli-cheatsheet.md)
|
|
242
|
+
- [Release checklist](docs/release.md)
|
|
243
|
+
- [Security policy](SECURITY.md)
|
|
244
|
+
- [Contributing and testing](CONTRIBUTING.md)
|
|
245
|
+
- [Roadmap](ROADMAP.md)
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
RubyDB is released under the [MIT License](LICENSE).
|
data/ROADMAP.md
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
# RubyDB roadmap
|
|
2
|
-
|
|
3
|
-
## Current phase: validated foundation
|
|
4
|
-
|
|
5
|
-
RubyDB has a durable storage/WAL/recovery foundation, transactions and MVCC,
|
|
6
|
-
the documented SQL engine, server/client protocol, Rails adapter coverage,
|
|
7
|
-
backups, logical replication, monitoring, fuzzing, and release automation.
|
|
8
|
-
The latest local audit passed 270 examples with zero failures.
|
|
9
|
-
|
|
10
|
-
## Next gates
|
|
11
|
-
|
|
12
|
-
1. Retain hosted Ruby/Rails/OS matrix evidence for each release.
|
|
13
|
-
2. Run physical filesystem quota, power-loss, corruption, restore, and compaction
|
|
14
|
-
drills on deployment targets.
|
|
15
|
-
3. Validate multi-host replication partitions, independent fencing, stale
|
|
16
|
-
primary rejection, and operator promotion procedures.
|
|
17
|
-
4. Complete certificate/secret rotation validation and an independent security
|
|
18
|
-
review.
|
|
19
|
-
5. Establish workload-specific latency, throughput, capacity, RPO, and RTO
|
|
20
|
-
baselines.
|
|
21
|
-
|
|
22
|
-
## Longer term
|
|
23
|
-
|
|
24
|
-
Expand the documented SQLite-style profile and only then consider broader
|
|
25
|
-
PostgreSQL/MySQL compatibility where implementation and semantic validation can
|
|
26
|
-
be maintained. Add automatic election only with an independently tested fencing
|
|
27
|
-
authority. Preserve correctness and explicit unsupported errors as hard gates.
|
|
1
|
+
# RubyDB roadmap
|
|
2
|
+
|
|
3
|
+
## Current phase: validated foundation
|
|
4
|
+
|
|
5
|
+
RubyDB has a durable storage/WAL/recovery foundation, transactions and MVCC,
|
|
6
|
+
the documented SQL engine, server/client protocol, Rails adapter coverage,
|
|
7
|
+
backups, logical replication, monitoring, fuzzing, and release automation.
|
|
8
|
+
The latest local audit passed 270 examples with zero failures.
|
|
9
|
+
|
|
10
|
+
## Next gates
|
|
11
|
+
|
|
12
|
+
1. Retain hosted Ruby/Rails/OS matrix evidence for each release.
|
|
13
|
+
2. Run physical filesystem quota, power-loss, corruption, restore, and compaction
|
|
14
|
+
drills on deployment targets.
|
|
15
|
+
3. Validate multi-host replication partitions, independent fencing, stale
|
|
16
|
+
primary rejection, and operator promotion procedures.
|
|
17
|
+
4. Complete certificate/secret rotation validation and an independent security
|
|
18
|
+
review.
|
|
19
|
+
5. Establish workload-specific latency, throughput, capacity, RPO, and RTO
|
|
20
|
+
baselines.
|
|
21
|
+
|
|
22
|
+
## Longer term
|
|
23
|
+
|
|
24
|
+
Expand the documented SQLite-style profile and only then consider broader
|
|
25
|
+
PostgreSQL/MySQL compatibility where implementation and semantic validation can
|
|
26
|
+
be maintained. Add automatic election only with an independently tested fencing
|
|
27
|
+
authority. Preserve correctness and explicit unsupported errors as hard gates.
|
data/Rakefile
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
|
|
9
|
-
RSpec::Core::RakeTask.new(:spec)
|
|
10
|
-
|
|
11
|
-
task default: %i[spec rubocop]
|
|
12
|
-
|
|
13
|
-
namespace :build do
|
|
14
|
-
desc
|
|
15
|
-
task checksum: :build do
|
|
16
|
-
gem_path = Dir[
|
|
17
|
-
abort
|
|
18
|
-
|
|
19
|
-
FileUtils.mkdir_p(
|
|
20
|
-
checksum_path = File.join(
|
|
21
|
-
File.write(checksum_path, "#{Digest::SHA512.file(gem_path).hexdigest} #{File.basename(gem_path)}\n")
|
|
22
|
-
puts "Wrote #{checksum_path}"
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
desc
|
|
27
|
-
task test: :spec
|
|
28
|
-
|
|
29
|
-
desc
|
|
30
|
-
RSpec::Core::RakeTask.new(:
|
|
31
|
-
t.pattern =
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
desc
|
|
35
|
-
RSpec::Core::RakeTask.new(:
|
|
36
|
-
t.pattern =
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
begin
|
|
40
|
-
require
|
|
41
|
-
RuboCop::RakeTask.new
|
|
42
|
-
rescue LoadError
|
|
43
|
-
# rubocop not installed
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
namespace :test do
|
|
47
|
-
desc
|
|
48
|
-
RSpec::Core::RakeTask.new(:concurrency) do |t|
|
|
49
|
-
t.pattern =
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
desc
|
|
53
|
-
RSpec::Core::RakeTask.new(:crash) do |t|
|
|
54
|
-
t.pattern =
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
desc
|
|
58
|
-
RSpec::Core::RakeTask.new(:chaos) do |t|
|
|
59
|
-
t.pattern =
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
desc
|
|
64
|
-
task :benchmark do
|
|
65
|
-
Dir[
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
desc
|
|
69
|
-
task :workload do
|
|
70
|
-
abort
|
|
71
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
|
+
require "rbconfig"
|
|
6
|
+
require "digest"
|
|
7
|
+
require "fileutils"
|
|
8
|
+
|
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
10
|
+
|
|
11
|
+
task default: %i[spec rubocop]
|
|
12
|
+
|
|
13
|
+
namespace :build do
|
|
14
|
+
desc "Build the gem and write a SHA-512 checksum for the exact artifact"
|
|
15
|
+
task checksum: :build do
|
|
16
|
+
gem_path = Dir["pkg/rubydb-*.gem"].max_by { |path| File.mtime(path) }
|
|
17
|
+
abort "No built gem found in pkg/" unless gem_path
|
|
18
|
+
|
|
19
|
+
FileUtils.mkdir_p("checksums")
|
|
20
|
+
checksum_path = File.join("checksums", "#{File.basename(gem_path)}.sha512")
|
|
21
|
+
File.write(checksum_path, "#{Digest::SHA512.file(gem_path).hexdigest} #{File.basename(gem_path)}\n")
|
|
22
|
+
puts "Wrote #{checksum_path}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc "Run all tests"
|
|
27
|
+
task test: :spec
|
|
28
|
+
|
|
29
|
+
desc "Run unit tests only"
|
|
30
|
+
RSpec::Core::RakeTask.new(:"test:unit") do |t|
|
|
31
|
+
t.pattern = "test/unit/**/*_spec.rb"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "Run integration tests only"
|
|
35
|
+
RSpec::Core::RakeTask.new(:"test:integration") do |t|
|
|
36
|
+
t.pattern = "test/integration/**/*_spec.rb"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
require "rubocop/rake_task"
|
|
41
|
+
RuboCop::RakeTask.new
|
|
42
|
+
rescue LoadError
|
|
43
|
+
# rubocop not installed
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
namespace :test do
|
|
47
|
+
desc "Run concurrency tests"
|
|
48
|
+
RSpec::Core::RakeTask.new(:concurrency) do |t|
|
|
49
|
+
t.pattern = "test/concurrency/**/*_spec.rb"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
desc "Run crash tests"
|
|
53
|
+
RSpec::Core::RakeTask.new(:crash) do |t|
|
|
54
|
+
t.pattern = "test/crash/**/*_spec.rb"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc "Run chaos tests"
|
|
58
|
+
RSpec::Core::RakeTask.new(:chaos) do |t|
|
|
59
|
+
t.pattern = "test/chaos/**/*_spec.rb"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
desc "Run benchmarks"
|
|
64
|
+
task :benchmark do
|
|
65
|
+
Dir["benchmarks/**/*.rb"].each { |f| load f }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
desc "Run the concurrent workload and durability verification"
|
|
69
|
+
task :workload do
|
|
70
|
+
abort "Concurrent workload failed" unless system(RbConfig.ruby, "benchmarks/concurrent_workload.rb")
|
|
71
|
+
end
|