rubydb 0.1.5 → 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/.gitignore +4 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +1 -1
- data/README.md +296 -227
- data/Rakefile +6 -1
- 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/README.md +8 -3
- data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +50 -42
- data/adapters/activerecord/rubydb-activerecord.gemspec +1 -1
- data/docs/README.md +3 -1
- data/docs/architecture/go-accelerator.md +179 -0
- data/docs/cli.md +24 -0
- data/docs/contributing/benchmarking.md +16 -0
- data/docs/developer/local-development.md +32 -0
- data/docs/release.md +2 -2
- data/lessons/02-local-development.md +2 -2
- data/lessons/04-rails-complex-apps.md +2 -2
- data/lessons/05-rubydb-production-server.md +2 -2
- data/lessons/07-hybrid-microservices.md +175 -90
- data/lessons/10-release-readiness.md +184 -117
- 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/cli/application.rb +6 -1
- data/lib/rubydb/cli/commands/accelerator.rb +72 -0
- data/lib/rubydb/cli/commands/doctor.rb +3 -0
- data/lib/rubydb/client/client.rb +7 -0
- data/lib/rubydb/client/connection.rb +15 -0
- data/lib/rubydb/client/result.rb +5 -1
- data/lib/rubydb/configuration/defaults.rb +12 -0
- data/lib/rubydb/configuration/validation.rb +8 -1
- data/lib/rubydb/execution/accelerator_dispatch.rb +30 -0
- data/lib/rubydb/execution/cost_model.rb +72 -0
- data/lib/rubydb/execution/executor.rb +373 -11
- data/lib/rubydb/execution/operator_selection.rb +57 -0
- data/lib/rubydb/execution/physical_plan.rb +47 -0
- data/lib/rubydb/execution/planner.rb +12 -46
- data/lib/rubydb/execution/sort_executor.rb +22 -8
- data/lib/rubydb/indexes/btree.rb +31 -2
- data/lib/rubydb/rubydb.rb +7 -1
- data/lib/rubydb/server/session.rb +45 -0
- data/lib/rubydb/storage/engine.rb +74 -12
- data/lib/rubydb/storage/snapshot_reader.rb +167 -0
- data/lib/rubydb/version.rb +1 -1
- data/lib/rubydb/wal/archive.rb +17 -0
- data/lib/rubydb/wal/wal.rb +1 -0
- data/rubydb.gemspec +12 -2
- data/scripts/build_accelerator +49 -0
- data/scripts/release +34 -4
- data/scripts/replication_failover_drill +2 -2
- metadata +49 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 643bd199d601eaacf6a2b0488799bc651a25198c4cd204ec61b80cd8242f735b
|
|
4
|
+
data.tar.gz: fe4f88a9a9570bbefb4f157cfef080e3f67d0828988f512d74df0a91d4564625
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f7a162c3df6d920a4f3826350d734419e6c77c8e4fcfa922171781dec37e4f48f3522c39bcff899ab489a56f21e4846ee608b3854444a6015c9de33c252d139
|
|
7
|
+
data.tar.gz: 643496af38ce2a262e8cd78c237b71df396a5eac3f376a21b7ec37f26c79c5d4c83a7c0d2b4e3f8c9acb51ba8f1f0f187bdf96fc3be74e5b97d2787e6d85a1d1
|
data/.gitignore
CHANGED
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
/adapters/python/build/
|
|
37
37
|
/adapters/python/dist/
|
|
38
38
|
/adapters/python/src/*.egg-info/
|
|
39
|
+
/adapters/rubydb/dist/
|
|
40
|
+
/adapters/rubydb/node_modules/
|
|
41
|
+
/examples/sveltekit_app/node_modules/
|
|
42
|
+
/examples/sveltekit_app/.svelte-kit/
|
|
39
43
|
__pycache__/
|
|
40
44
|
*.py[cod]
|
|
41
45
|
|
data/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,20 @@ All notable changes to RubyDB are documented here. Versions follow
|
|
|
23
23
|
vacuum, maintenance, and release workflows.
|
|
24
24
|
- Clarified the tested common SQLite-style profile and production limits.
|
|
25
25
|
|
|
26
|
+
## 0.1.6 - 2026-09-18
|
|
27
|
+
|
|
28
|
+
- Bundled the Go accelerator binaries and Ruby bridge for release installs;
|
|
29
|
+
developers do not need Go installed to use the packaged core gem.
|
|
30
|
+
- Added lock-protected direct storage snapshots, worker lifecycle recovery,
|
|
31
|
+
multiplexed requests, cancellation, bounded execution, and adaptive Ruby/Go
|
|
32
|
+
selection with a safe Ruby fallback.
|
|
33
|
+
- Added accelerator CLI diagnostics, environment-mode handling, checksums,
|
|
34
|
+
extracted-gem verification, and release packaging for the runtime binaries.
|
|
35
|
+
- Added the Rails ecommerce pressure example and expanded production guidance
|
|
36
|
+
for embedded development, managed RubyDB services, PostgreSQL-backed large
|
|
37
|
+
applications, and ActiveRecord adapter deployment.
|
|
38
|
+
- Prepared `rubydb-activerecord` 0.1.3 for the RubyDB 0.1.x release line.
|
|
39
|
+
|
|
26
40
|
## 0.1.5 - 2026-09-10
|
|
27
41
|
|
|
28
42
|
- Applied network query and prepared-statement parameters through the server
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,249 +1,318 @@
|
|
|
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
|
-
|
|
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
23
|
Use PostgreSQL as the default system of record for massive applications,
|
|
24
24
|
high-concurrency public products, large shared Rails applications, advanced
|
|
25
25
|
PostgreSQL SQL/extensions, and workloads requiring a mature managed database
|
|
26
26
|
ecosystem. A common production architecture is PostgreSQL for the main app and
|
|
27
27
|
RubyDB for smaller, independently operated microservices.
|
|
28
28
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- Ruby API
|
|
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
|
-
|
|
29
|
+
## Ecosystem and community adapters
|
|
30
|
+
|
|
31
|
+
RubyDB's ecosystem is built around a clear boundary: application code connects
|
|
32
|
+
to a RubyDB server through the documented client/server protocol. The embedded
|
|
33
|
+
`.rdb` file format is an internal storage implementation, not a public API for
|
|
34
|
+
third-party drivers. This lets RubyDB evolve its storage safely while language
|
|
35
|
+
and framework communities build clients that share the same server behavior.
|
|
36
|
+
|
|
37
|
+
Official integration surfaces include:
|
|
38
|
+
|
|
39
|
+
- Ruby's direct API and the `rubydb` client/server client
|
|
40
|
+
- `rubydb-activerecord` for Rails applications
|
|
41
|
+
- `rubydb-python` for Python DB-API 2.0 applications
|
|
42
|
+
- `rubydb-node` for Node.js and TypeScript applications
|
|
43
|
+
- Sequel and other Ruby integrations documented under `adapters/`
|
|
44
|
+
|
|
45
|
+
Community developers can create adapters for another language, framework,
|
|
46
|
+
ORM, query builder, migration tool, observability system, or job framework.
|
|
47
|
+
Every adapter should begin with the [server protocol](docs/server/protocol.md)
|
|
48
|
+
and the executable protocol tests, then provide an idiomatic API for its
|
|
49
|
+
community. A production adapter must preserve parameter binding, transaction
|
|
50
|
+
ownership, deadlines and wire cancellation, TLS verification, bounded frames,
|
|
51
|
+
error details, and clean connection shutdown. A wrapper that only sends a
|
|
52
|
+
string of SQL is not a production adapter.
|
|
53
|
+
|
|
54
|
+
Use a distinct package name such as `rubydb-go`, `rubydb-django`, or
|
|
55
|
+
`@your-scope/rubydb` and make its ownership clear. Do not present a community
|
|
56
|
+
package as an official RubyDB release. Add the adapter to the ecosystem list
|
|
57
|
+
only after it has live integration tests against a real RubyDB server and its
|
|
58
|
+
supported RubyDB versions are documented. The complete build, test, security,
|
|
59
|
+
and publishing workflow is in
|
|
60
|
+
[Lesson 11: Build a community adapter](lessons/11-community-adapter.md).
|
|
61
|
+
|
|
62
|
+
## What works today
|
|
63
|
+
|
|
64
|
+
The repository contains implementation and automated coverage for:
|
|
65
|
+
|
|
66
|
+
- SQL tables, CRUD, joins, grouping and aggregates, ordering, transactions,
|
|
67
|
+
savepoints, conflict handling, and documented maintenance statements
|
|
68
|
+
- typed values, primary/foreign keys, unique and check constraints, and B-tree
|
|
69
|
+
indexes
|
|
70
|
+
- durable storage, WAL-backed commits, recovery, snapshots, branching, and
|
|
71
|
+
MVCC paths
|
|
72
|
+
- Ruby API, client/server protocol, connection pooling, configuration, and
|
|
73
|
+
operational tooling
|
|
74
|
+
- ActiveRecord integration, Rails migrations, and a runnable Rails example
|
|
75
|
+
|
|
76
|
+
These features are not a guarantee of compatibility with every application.
|
|
77
|
+
Run the test suite and validate your own schema, queries, workload, backup,
|
|
78
|
+
restore, and failure scenarios before using RubyDB for important data.
|
|
79
|
+
|
|
80
|
+
## Why “complete PostgreSQL/MySQL/SQLite compatibility” matters
|
|
81
|
+
|
|
82
|
+
That requirement is only necessary when RubyDB is intended to be a drop-in
|
|
83
|
+
replacement for an existing application using one of those databases.
|
|
84
|
+
|
|
85
|
+
It includes much more than accepting similar `SELECT` statements:
|
|
86
|
+
|
|
87
|
+
- dialect-specific SQL syntax, functions, operators, casts, and error behavior
|
|
88
|
+
- query semantics for joins, `NULL`, ordering, grouping, subqueries, CTEs,
|
|
89
|
+
unions, upserts, and window functions
|
|
90
|
+
- data types, indexes, constraints, generated values, and transaction behavior
|
|
91
|
+
- migration behavior and ActiveRecord adapter mappings
|
|
92
|
+
- client protocol, connection behavior, locking, limits, and operational tools
|
|
93
|
+
|
|
94
|
+
A new Ruby or Rails application does not need complete compatibility. It can
|
|
95
|
+
use RubyDB's documented SQL and adapter behavior directly. Compatibility is
|
|
96
|
+
needed to move an existing PostgreSQL, MySQL, or SQLite application without
|
|
97
|
+
rewriting queries and without discovering semantic differences in production.
|
|
98
|
+
|
|
99
|
+
RubyDB currently targets a documented RubyDB SQL subset plus tested Rails
|
|
100
|
+
operations. The compatibility documents describe the supported statements;
|
|
101
|
+
unsupported or unverified dialect features must not be assumed to work.
|
|
102
|
+
|
|
103
|
+
## Quick start
|
|
104
|
+
|
|
105
|
+
Install the core release gem:
|
|
73
106
|
|
|
74
107
|
```sh
|
|
75
|
-
gem install rubydb
|
|
108
|
+
gem install rubydb -v 0.1.6
|
|
76
109
|
```
|
|
77
110
|
|
|
78
|
-
For
|
|
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:
|
|
111
|
+
For Rails, install the core and ActiveRecord adapter together:
|
|
163
112
|
|
|
164
113
|
```ruby
|
|
165
114
|
# Gemfile
|
|
166
|
-
gem "
|
|
115
|
+
gem "rubydb", "~> 0.1.6"
|
|
116
|
+
gem "rubydb-activerecord", "~> 0.1.3"
|
|
167
117
|
```
|
|
168
118
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
119
|
+
RubyDB ships the Go accelerator binaries inside the core gem. Developers and
|
|
120
|
+
deployments do not install Go. The default `accelerator.mode: auto` starts Go
|
|
121
|
+
for eligible workloads and keeps it only when the result is equivalent and
|
|
122
|
+
the measured latency wins; use `RUBYDB_ACCELERATOR=required` for a readiness
|
|
123
|
+
check that must exercise Go, or `RUBYDB_ACCELERATOR=off` for Ruby-only
|
|
124
|
+
diagnostics.
|
|
125
|
+
|
|
126
|
+
For local development from this repository:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bundle install
|
|
130
|
+
bundle exec rspec
|
|
174
131
|
```
|
|
175
132
|
|
|
176
|
-
|
|
177
|
-
migrations once from a release job, and validate the application against the
|
|
178
|
-
same PostgreSQL major version used in production.
|
|
133
|
+
### Bundled Go acceleration
|
|
179
134
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
The
|
|
183
|
-
|
|
184
|
-
|
|
135
|
+
RubyDB keeps the Ruby engine as its correctness authority and automatically
|
|
136
|
+
starts a bundled, CGO-free Go worker for proven read-only pipelines, checksums,
|
|
137
|
+
and compression. The release gem contains platform binaries; end users do not
|
|
138
|
+
install or configure Go. From a source checkout, build and verify the worker
|
|
139
|
+
with:
|
|
185
140
|
|
|
186
141
|
```sh
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
bundle exec ruby bin/rails db:migrate
|
|
190
|
-
bundle exec ruby bin/rails server -b 127.0.0.1 -p 3001
|
|
142
|
+
ruby scripts/build_accelerator
|
|
143
|
+
ruby -Ilib exe/rubydb accelerator --ping --json
|
|
191
144
|
```
|
|
192
145
|
|
|
193
|
-
|
|
194
|
-
`
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
146
|
+
Use `accelerator.mode: off` or `RUBYDB_ACCELERATOR=off` for Ruby-only
|
|
147
|
+
diagnostics. `mode: auto` calibrates eligible scans, aggregates, and inner
|
|
148
|
+
hash joins against Ruby and keeps Go only when it wins without changing the
|
|
149
|
+
result. Use `required` only for differential validation and readiness checks.
|
|
150
|
+
See [the accelerator architecture](docs/architecture/go-accelerator.md)
|
|
151
|
+
for the protocol boundary, fallback behavior, differential testing, and
|
|
152
|
+
release rules.
|
|
153
|
+
|
|
154
|
+
## Ruby usage
|
|
155
|
+
|
|
156
|
+
RubyDB can run embedded in a single owning process:
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
require "rubydb"
|
|
160
|
+
|
|
161
|
+
engine = RubyDB::Storage::Engine.new("tmp/example.rdb")
|
|
162
|
+
engine.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
|
|
163
|
+
engine.execute("INSERT INTO users (name) VALUES ('Aldane')")
|
|
164
|
+
puts engine.execute("SELECT * FROM users").inspect
|
|
165
|
+
engine.close
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
For multiple application processes, use RubyDB's server/client mode and point
|
|
169
|
+
clients at the managed server. Do not open the same embedded database path
|
|
170
|
+
from multiple independent processes. A regular Ruby application can use a
|
|
171
|
+
RubyDB connection URL supplied by its environment:
|
|
172
|
+
|
|
173
|
+
```ruby
|
|
174
|
+
client = RubyDB::Client::Client.new(url: ENV.fetch("RUBYDB_URL"))
|
|
175
|
+
client.query("SELECT 1")
|
|
176
|
+
client.disconnect
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Use the `rubydb://` or TLS-enabled `rubydbs://` format documented in the Rails
|
|
180
|
+
configuration guide. RubyDB URLs are not PostgreSQL URLs.
|
|
181
|
+
|
|
182
|
+
## Copy-and-paste examples
|
|
183
|
+
|
|
184
|
+
### RubyDB for local development
|
|
185
|
+
|
|
186
|
+
This creates a durable local database in one owning Ruby process:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
require "rubydb"
|
|
190
|
+
|
|
191
|
+
engine = RubyDB::Storage::Engine.new("tmp/development.rdb")
|
|
192
|
+
begin
|
|
193
|
+
engine.execute("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL)")
|
|
194
|
+
engine.execute("INSERT INTO notes (body) VALUES ('First note')")
|
|
195
|
+
puts engine.execute("SELECT id, body FROM notes ORDER BY id").inspect
|
|
196
|
+
ensure
|
|
197
|
+
engine.close
|
|
198
|
+
end
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Do not open the same embedded path from separate web and worker processes.
|
|
202
|
+
|
|
203
|
+
### RubyDB for a production microservice
|
|
204
|
+
|
|
205
|
+
Run one RubyDB server on persistent storage and inject a TLS URL into the
|
|
206
|
+
service:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
gem install rubydb -v 0.1.6
|
|
210
|
+
rubydb --config /etc/rubydb/production.yml --env production start
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```ruby
|
|
214
|
+
require "rubydb"
|
|
215
|
+
|
|
216
|
+
client = RubyDB::Client::Client.new(url: ENV.fetch("RUBYDB_URL"))
|
|
217
|
+
begin
|
|
218
|
+
puts client.query("SELECT 1").to_hash
|
|
219
|
+
ensure
|
|
220
|
+
client.disconnect
|
|
221
|
+
end
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Use a URL such as `rubydbs://user:URL_ENCODED_PASSWORD@db.internal:7432/app`
|
|
225
|
+
with TLS verification enabled. Store the complete URL in a secret manager and
|
|
226
|
+
keep the database service on a private network.
|
|
227
|
+
|
|
228
|
+
### PostgreSQL for a massive Rails application
|
|
229
|
+
|
|
230
|
+
Use the `pg` gem and a managed PostgreSQL connection string for the main
|
|
231
|
+
application:
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
# Gemfile
|
|
235
|
+
gem "pg"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
# config/database.yml
|
|
240
|
+
production:
|
|
241
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
|
242
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Set `DATABASE_URL` through the hosting provider’s secret settings, run
|
|
246
|
+
migrations once from a release job, and validate the application against the
|
|
247
|
+
same PostgreSQL major version used in production.
|
|
248
|
+
|
|
249
|
+
## Rails example
|
|
250
|
+
|
|
251
|
+
The small Rails 7.2 application in
|
|
252
|
+
[`examples/rails_app`](examples/rails_app) runs a real migration, model query,
|
|
253
|
+
and browser form through `rubydb-activerecord`.
|
|
254
|
+
|
|
255
|
+
```sh
|
|
256
|
+
cd examples/rails_app
|
|
257
|
+
bundle install
|
|
258
|
+
bundle exec ruby bin/rails db:migrate
|
|
259
|
+
bundle exec ruby bin/rails server -b 127.0.0.1 -p 3001
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Open <http://127.0.0.1:3001/>. The example uses an embedded database under
|
|
263
|
+
`tmp/`; set `RUBYDB_DATABASE` to choose another path. See the adapter and Rails
|
|
264
|
+
documentation for network configuration, migrations, production deployment,
|
|
265
|
+
backups, restore drills, and monitoring.
|
|
266
|
+
|
|
267
|
+
For an even smaller end-to-end smoke test, see the tiny GitHub-style app in
|
|
268
|
+
[`examples/github_clone`](examples/github_clone). It covers repositories,
|
|
269
|
+
issues, commits, Rails associations, foreign keys, indexes, seed data, and a
|
|
270
|
+
browser page backed by RubyDB.
|
|
271
|
+
|
|
272
|
+
## Compatibility policy
|
|
273
|
+
|
|
274
|
+
RubyDB does not claim complete PostgreSQL, MySQL, or SQLite compatibility until
|
|
275
|
+
each compatibility area has both an implementation and repeatable validation.
|
|
276
|
+
The project must validate at least:
|
|
277
|
+
|
|
278
|
+
1. parser and execution behavior for the documented dialect surface
|
|
279
|
+
2. type, constraint, transaction, locking, and error semantics
|
|
280
|
+
3. ActiveRecord queries, joins, eager loading, associations, and migrations
|
|
281
|
+
4. sustained concurrency, cancellation, recovery, backup/restore, and failover
|
|
282
|
+
5. supported Ruby, Rails, operating-system, and client/server combinations
|
|
283
|
+
|
|
284
|
+
Until then, compatibility should be treated as feature-specific, not implied
|
|
285
|
+
by the presence of an adapter.
|
|
286
|
+
|
|
287
|
+
## Documentation
|
|
288
|
+
|
|
289
|
+
- [Documentation index](docs/README.md)
|
|
290
|
+
- [Production journey](lessons/01-foundations.md)
|
|
291
|
+
- [Developer guide](docs/developer-guide.md)
|
|
292
|
+
- [Troubleshooting guide](docs/troubleshooting.md)
|
|
293
|
+
- [Debugging playbook](docs/debugging.md)
|
|
294
|
+
- [Production operations guide](docs/operations/production-guide.md)
|
|
295
|
+
- [Lessons learned](docs/lessons-learned.md)
|
|
296
|
+
- [Getting started](docs/getting-started/quickstart.md)
|
|
297
|
+
- [Local development to production](docs/getting-started/local-to-production.md)
|
|
298
|
+
- [SQL compatibility](docs/sql/compatibility.md)
|
|
299
|
+
- [SQL compatibility guide](docs/sql/compatibility-guide.md)
|
|
300
|
+
- [SQLite compatibility profile](docs/sql/sqlite-compatibility.md)
|
|
301
|
+
- [SQL syntax](docs/sql/syntax.md)
|
|
302
|
+
- [Rails installation](docs/rails/installation.md)
|
|
303
|
+
- [Rails production guidance](docs/rails/production.md)
|
|
304
|
+
- [Rails compatibility guide](docs/rails/compatibility-guide.md)
|
|
305
|
+
- [Python adapter](adapters/python/README.md)
|
|
306
|
+
- [Production readiness](docs/production-readiness.md)
|
|
307
|
+
- [Operations and workload testing](docs/operations/workload-testing.md)
|
|
308
|
+
- [Production runbook](docs/operations/production-runbook.md)
|
|
309
|
+
- [CLI guide](docs/cli.md)
|
|
310
|
+
- [CLI cheat sheet](docs/cli-cheatsheet.md)
|
|
311
|
+
- [Release checklist](docs/release.md)
|
|
312
|
+
- [Security policy](SECURITY.md)
|
|
313
|
+
- [Contributing and testing](CONTRIBUTING.md)
|
|
314
|
+
- [Roadmap](ROADMAP.md)
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
RubyDB is released under the [MIT License](LICENSE).
|
data/Rakefile
CHANGED
|
@@ -11,8 +11,13 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
11
11
|
task default: %i[spec rubocop]
|
|
12
12
|
|
|
13
13
|
namespace :build do
|
|
14
|
+
desc "Build the bundled Go accelerator for the current platform"
|
|
15
|
+
task :accelerator do
|
|
16
|
+
abort "Go accelerator build failed" unless system({"RUBYDB_ACCELERATOR_TARGETS" => "current"}, RbConfig.ruby, "scripts/build_accelerator")
|
|
17
|
+
end
|
|
18
|
+
|
|
14
19
|
desc "Build the gem and write a SHA-512 checksum for the exact artifact"
|
|
15
|
-
task checksum: :build do
|
|
20
|
+
task checksum: [:accelerator, :build] do
|
|
16
21
|
gem_path = Dir["pkg/rubydb-*.gem"].max_by { |path| File.mtime(path) }
|
|
17
22
|
abort "No built gem found in pkg/" unless gem_path
|
|
18
23
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
ceeaad8692cfdc0e7b72b85d2c17b5e23c754d5f1159590df142fcfa857b8ff3 rubydb-accelerator-darwin-amd64
|
|
2
|
+
1ab2ca6b7294f7d97ff4e816a5ad504802e84e4c196146a199a145a74829e3a0 rubydb-accelerator-darwin-arm64
|
|
3
|
+
a0d141e3c41f2709d5bbaa67dd856f28805e4c2cbbc1034826e190877aa05aad rubydb-accelerator-linux-amd64
|
|
4
|
+
445b164c71284ce6432215fcf1213a99497194b3c8da6ea9577602405de4cf38 rubydb-accelerator-linux-arm64
|
|
5
|
+
9e5c4f9acc9fe9751d5c945956fdbec50f9c698a2b5a0366255edef700a1499d rubydb-accelerator-windows-amd64.exe
|
|
6
|
+
3dd6aa97761f00a4552fa21a16571598bdfef8850347202ee4131d88ee97d002 rubydb-accelerator-windows-arm64.exe
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|