rubydb 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b474095677d024d7aae488865411803476f0c5040d75fba89b063f0e9679a3d9
4
- data.tar.gz: 18a4bbf0d5744c8e980a50ee4b6ee6a75133f299a96eabd458ca1bf40554bb78
3
+ metadata.gz: 5cfc85dc4d3cfca89bd7d89335e4bf887fbfca212836f8a62d92a70a63f0f284
4
+ data.tar.gz: 9869f03b9da1a7e0cfd0c01f1f22ae9b5ba0e2b12eedaeac72e1b4deab878a0b
5
5
  SHA512:
6
- metadata.gz: a719c2d1f1de9e98ac56a45ab3956ce5b216dd1987e510688af3d71cfe131f98463cbab9525ca96ef2cc34a4457d3475b65016f8595a9f4f3c9b5f621a503247
7
- data.tar.gz: b0f0d139f3da9c4eb8bea8805cbefeff6c11dae8dcf47853b8a157b402e4c10103bbf8b94a84a8ef1d80c7fe07a63e2effa042bff21d6ac3591b7340ff6c1b55
6
+ metadata.gz: 76650c2403e26244619687eb6146bb7a1561d3764d664094a6deb94e02566924c60979f481aca972be026987775f8c9b68ed02804d15e583f885528e02833613
7
+ data.tar.gz: 60c894fde163c1a47ed84aa2c2d8b374a9b6c70f3d810feb7ca419a06aa2cb5e6026d8aa278d27ed89ad4a83b48405c31137671f1d2dab7240d0efc36b367de8
data/CHANGELOG.md CHANGED
@@ -3,7 +3,7 @@
3
3
  All notable changes to RubyDB are documented here. Versions follow
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
- ## Unreleased
6
+ ## Unreleased
7
7
 
8
8
  - Added full developer, troubleshooting, debugging, production operations,
9
9
  Rails compatibility, and SQL compatibility guides with repository maps,
@@ -21,9 +21,25 @@ All notable changes to RubyDB are documented here. Versions follow
21
21
  - Added a full CLI guide and cheat sheet covering lifecycle, server operation,
22
22
  shell, migrations, backup/restore, snapshots, branches, inspection, doctor,
23
23
  vacuum, maintenance, and release workflows.
24
- - Clarified the tested common SQLite-style profile and production limits.
25
-
26
- ## 0.1.0 - 2026-09-07
24
+ - Clarified the tested common SQLite-style profile and production limits.
25
+
26
+ ## 0.1.2 - 2026-09-09
27
+
28
+ - Added SQLite/ActiveRecord-compatible `INSERT ... DEFAULT VALUES` parsing,
29
+ planning, execution, default materialization, and regression coverage.
30
+ - Normalized literal schema defaults before they reach physical rows so empty
31
+ strings and other scalar defaults are not persisted as AST wrapper objects.
32
+ - Released `rubydb-activerecord` 0.1.1 with scalar default unwrapping for
33
+ ActiveRecord column metadata.
34
+
35
+ ## 0.1.1 - 2026-09-09
36
+
37
+ - Published the Rails connection configuration fixes for embedded database
38
+ paths and `rubydb://`/`rubydbs://` connection URLs.
39
+ - Kept the patch release compatible with the RubyDB 0.1.x adapter dependency
40
+ range.
41
+
42
+ ## 0.1.0 - 2026-09-07
27
43
 
28
44
  - Initial public release candidate.
29
45
  - Includes the embedded engine, ActiveRecord adapter, backup/recovery, WAL,
@@ -1,9 +1,133 @@
1
- # RubyDB ActiveRecord adapter
2
-
3
- The `rubydb-activerecord` gem connects Rails applications to RubyDB through
4
- ActiveRecord. It supports embedded RubyDB engines and network connections.
5
-
6
- For an executable Rails 7.2 example, see
7
- [`examples/rails_app`](../../examples/rails_app). The example includes a
8
- database configuration, migration, model/controller, browser form, and a
9
- smoke test that exercises the adapter against a real RubyDB engine.
1
+ # rubydb-activerecord
2
+
3
+ `rubydb-activerecord` is the ActiveRecord adapter for [RubyDB](https://github.com/aldanedev-create/rubydb). It lets Rails applications use RubyDB through the normal model, relation, transaction, migration, schema, and connection-pool APIs.
4
+
5
+ This gem is an adapter to RubyDB's SQL engine. It is not a PostgreSQL, MySQL, or SQLite wire-protocol compatibility layer, and it does not make arbitrary dialect-specific SQL portable. Validate your application's queries and migrations against the exact Ruby, Rails, RubyDB, operating-system, and deployment versions you will run.
6
+
7
+ ## Requirements
8
+
9
+ - Ruby 3.3 or newer
10
+ - RubyDB 0.1.x
11
+ - ActiveRecord 7.1, 7.2, or 8.0 (the dependency range is `>= 7.1`, `< 8.1`)
12
+
13
+ ## Install
14
+
15
+ Add both gems to the Rails application's `Gemfile`:
16
+
17
+ ```ruby
18
+ gem "rubydb"
19
+ gem "rubydb-activerecord"
20
+ ```
21
+
22
+ Then run:
23
+
24
+ ```sh
25
+ bundle install
26
+ ```
27
+
28
+ The adapter registers itself under the `rubydb` adapter name when it is
29
+ required by Bundler. For a manually loaded application, require it explicitly:
30
+
31
+ ```ruby
32
+ require "rubydb"
33
+ require "active_record/connection_adapters/rubydb_adapter"
34
+ ```
35
+
36
+ ## Development: embedded database
37
+
38
+ Embedded mode is convenient for local development and a controlled
39
+ single-process application. The process owns the database file:
40
+
41
+ ```yaml
42
+ # config/database.yml
43
+ development:
44
+ adapter: rubydb
45
+ embedded: true
46
+ database: <%= Rails.root.join("tmp/development.rdb") %>
47
+ ```
48
+
49
+ Run migrations normally:
50
+
51
+ ```sh
52
+ bin/rails db:migrate
53
+ bin/rails console
54
+ bin/rails server
55
+ ```
56
+
57
+ Do not open the same embedded path from multiple independent Rails processes.
58
+ For multiple web workers, job workers, or hosts, use a managed RubyDB server.
59
+
60
+ ## Production: managed server
61
+
62
+ Use a network connection when the application has more than one process or
63
+ when the database must be operated independently from the application. Keep
64
+ credentials in the platform secret manager and map them into `database.yml`:
65
+
66
+ ```yaml
67
+ # config/database.yml
68
+ production:
69
+ adapter: rubydb
70
+ embedded: false
71
+ url: <%= ENV.fetch("RUBYDB_URL") %>
72
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
73
+ timeout: <%= ENV.fetch("RUBYDB_TIMEOUT", "30") %>
74
+ ```
75
+
76
+ Use `rubydb://` for a plain private-network connection or `rubydbs://` for TLS:
77
+
78
+ ```text
79
+ rubydbs://app_user:URL_ENCODED_PASSWORD@db.internal.example:7432/app?verify_peer=true&ca_file=%2Fetc%2Frubydb%2Ftls%2Fca.crt
80
+ ```
81
+
82
+ The server must be deployed separately with persistent storage,
83
+ authentication, TLS, backups, monitoring, resource limits, and a tested
84
+ restore procedure. Size its connection limit for the total Rails pool across
85
+ all application processes, with headroom for administration and replication.
86
+ See the repository's [Rails database configuration](../../docs/rails/database-yml.md)
87
+ and [production guidance](../../docs/rails/production.md).
88
+
89
+ ## Adapter surface
90
+
91
+ The release test suite exercises:
92
+
93
+ - ActiveRecord CRUD, binds, quoted identifiers, type casting, and false/zero values
94
+ - transactions and savepoints
95
+ - `joins`, qualified filters, ordering, eager loading, and nested associations
96
+ - table/column/index/foreign-key introspection
97
+ - Rails migrations, defaults, indexes, schema dumps, and populated-table changes
98
+ - embedded and network connection setup paths
99
+
100
+ RubyDB currently has documented SQL and schema boundaries. Features outside
101
+ the tested surface—such as dialect-specific extensions, generated columns,
102
+ complex table rebuilds, or application-specific Arel—need explicit tests
103
+ before deployment.
104
+
105
+ ## Validation
106
+
107
+ Run the adapter's integration suite from this directory:
108
+
109
+ ```sh
110
+ bundle install
111
+ bundle exec rspec spec
112
+ ```
113
+
114
+ Run the repository's Rails-focused checks from the repository root:
115
+
116
+ ```sh
117
+ bundle exec rspec spec/rails_adapter_live_engine_spec.rb spec/rails_adapter_schema_dump_spec.rb spec/rails_schema_statements_spec.rb
118
+ ```
119
+
120
+ Before a production release, run a real migration and smoke query through the
121
+ same server URL, TLS settings, pool size, and secret-management path used by
122
+ the deployment. Keep a verified backup before migrations and rehearse restore
123
+ and rollback on a representative copy.
124
+
125
+ ## Support and release policy
126
+
127
+ The adapter version is coupled to the RubyDB 0.1.x release line. Pin both gems
128
+ in the application lockfile, upgrade them together, and run the adapter suite
129
+ before upgrading Rails. Report reproducible adapter or engine issues at the
130
+ project's [issue tracker](https://github.com/aldanedev-create/rubydb/issues)
131
+ with Ruby/Rails/RubyDB versions, the SQL or migration involved, and a redacted
132
+ configuration summary. Never include passwords, connection URLs, database
133
+ files, or private keys in reports.
@@ -756,10 +756,15 @@ module ActiveRecord
756
756
 
757
757
  # ActiveRecord's generic Column deduplication is string-oriented. RubyDB
758
758
  # persists typed defaults, so serialize scalar defaults at this boundary
759
- # and let ActiveRecord cast them through the column type map.
760
- def rails_default_value(value)
761
- value.is_a?(String) ? value : value.to_s
762
- end
759
+ # and let ActiveRecord cast them through the column type map.
760
+ def rails_default_value(value)
761
+ # RubyDB exposes SQL defaults as AST literals. ActiveRecord expects
762
+ # the scalar payload when it builds its Column metadata; calling
763
+ # `to_s` on the wrapper would leak the Ruby object inspection into
764
+ # newly instantiated records.
765
+ value = value.value if value.respond_to?(:value) && !value.is_a?(String)
766
+ value.is_a?(String) ? value : value.to_s
767
+ end
763
768
 
764
769
  def sql_for_execution(sql)
765
770
  sql = sql.to_sql if sql.respond_to?(:to_sql)
@@ -775,9 +780,15 @@ module ActiveRecord
775
780
  column.is_a?(Hash) ? (column[:name] || column["name"] || column) : column
776
781
  end.map(&:to_s)
777
782
  end
778
- values = rows.map do |row|
779
- columns.map { |column| row[column] || row[column.to_sym] }
780
- end
783
+ values = rows.map do |row|
784
+ columns.map do |column|
785
+ if row.respond_to?(:key?) && row.key?(column)
786
+ row[column]
787
+ elsif row.respond_to?(:key?) && row.key?(column.to_sym)
788
+ row[column.to_sym]
789
+ end
790
+ end
791
+ end
781
792
  ActiveRecord::Result.new(columns, values)
782
793
  end
783
794
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "rubydb-activerecord"
5
- spec.version = "0.1.0"
5
+ spec.version = "0.1.1"
6
6
  spec.authors = ["Aldane Hutchinson"]
7
7
  spec.email = ["aldanehutchinson5@gmail.com"]
8
8
 
@@ -10,12 +10,17 @@ Gem::Specification.new do |spec|
10
10
  spec.description = "ActiveRecord adapter for the RubyDB database"
11
11
  spec.homepage = "https://github.com/aldanedev-create/rubydb"
12
12
  spec.license = "MIT"
13
- spec.required_ruby_version = ">= 3.2.0"
14
-
15
- spec.metadata["homepage_uri"] = spec.homepage
16
- spec.metadata["source_code_uri"] = spec.homepage
17
-
18
- spec.files = Dir.glob("lib/**/*.rb") + %w[README.md]
13
+ # rubydb itself requires Ruby 3.3 or newer. Keep the adapter's runtime
14
+ # contract aligned so Bundler cannot select an unsupported combination.
15
+ spec.required_ruby_version = ">= 3.3.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "#{spec.homepage}/tree/main/adapters/activerecord"
19
+ spec.metadata["bug_tracker_uri"] = "https://github.com/aldanedev-create/rubydb/issues"
20
+ spec.metadata["changelog_uri"] = "https://github.com/aldanedev-create/rubydb/blob/main/CHANGELOG.md"
21
+ spec.metadata["documentation_uri"] = "https://github.com/aldanedev-create/rubydb/tree/main/docs"
22
+
23
+ spec.files = Dir.glob("lib/**/*.rb") + %w[README.md rubydb-activerecord.gemspec]
19
24
  spec.require_paths = ["lib"]
20
25
 
21
26
  spec.add_dependency "activerecord", ">= 7.1", "< 8.1"
@@ -31,17 +31,27 @@ RSpec.describe ActiveRecord::ConnectionAdapters::RubyDBAdapter do
31
31
  end
32
32
  end
33
33
 
34
- it "creates and finds an ActiveRecord model through the embedded engine" do
34
+ it "creates and finds an ActiveRecord model through the embedded engine" do
35
35
  connection = ActiveRecord::Base.connection
36
36
  connection.execute("CREATE TABLE accounts (id INTEGER PRIMARY KEY, email VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL)")
37
37
 
38
38
  created = model.create!(id: 1, email: "ada@example.test", active: true)
39
39
  loaded = model.find(created.id)
40
40
 
41
- expect(loaded.attributes).to include("id" => 1, "email" => "ada@example.test", "active" => true)
42
- end
43
-
44
- it "runs a Rails migration that creates a table, adds a column, and adds an index" do
41
+ expect(loaded.attributes).to include("id" => 1, "email" => "ada@example.test", "active" => true)
42
+ end
43
+
44
+ it "preserves false and zero values in ActiveRecord results" do
45
+ connection = ActiveRecord::Base.connection
46
+ connection.execute("CREATE TABLE flags (id INTEGER PRIMARY KEY, enabled BOOLEAN NOT NULL, attempts INTEGER NOT NULL)")
47
+ connection.execute("INSERT INTO flags (id, enabled, attempts) VALUES (1, FALSE, 0)")
48
+
49
+ result = connection.exec_query("SELECT enabled, attempts FROM flags WHERE id = 1")
50
+
51
+ expect(result.first).to include("enabled" => false, "attempts" => 0)
52
+ end
53
+
54
+ it "runs a Rails migration that creates a table, adds a column, and adds an index" do
45
55
  migration = Class.new(ActiveRecord::Migration[migration_version]) do
46
56
  def change
47
57
  create_table :projects do |table|
@@ -64,10 +74,22 @@ RSpec.describe ActiveRecord::ConnectionAdapters::RubyDBAdapter do
64
74
  expect(schema).not_to include('t.integer "id"')
65
75
 
66
76
  migration.new.migrate(:down)
67
- expect(connection.table_exists?(:projects)).to be(false)
68
- end
69
-
70
- it "executes an ActiveRecord association join with qualified filtering" do
77
+ expect(connection.table_exists?(:projects)).to be(false)
78
+ end
79
+
80
+ it "exposes scalar schema defaults to ActiveRecord" do
81
+ connection = ActiveRecord::Base.connection
82
+ connection.execute("CREATE TABLE settings (id INTEGER PRIMARY KEY, label VARCHAR(255) NOT NULL DEFAULT '')")
83
+
84
+ settings_model = Class.new(ActiveRecord::Base) do
85
+ self.table_name = "settings"
86
+ end
87
+
88
+ expect(settings_model.new.label).to eq("")
89
+ expect(settings_model.create!.reload.label).to eq("")
90
+ end
91
+
92
+ it "executes an ActiveRecord association join with qualified filtering" do
71
93
  stub_const("RubydbAccount", Class.new(ActiveRecord::Base) do
72
94
  self.table_name = "accounts"
73
95
  has_many :rubydb_projects, class_name: "RubydbProject", foreign_key: :account_id
@@ -124,14 +124,15 @@ module RubyDB
124
124
  end
125
125
 
126
126
  class Insert < Plan
127
- attr_reader :values, :rows, :on_conflict
128
-
129
- def initialize(table_name, columns = [], values = [], rows: nil, on_conflict: nil)
130
- super(:insert, table_name, columns)
131
- @rows = rows || [values]
132
- @values = @rows.first || []
133
- @on_conflict = on_conflict
134
- end
127
+ attr_reader :values, :rows, :on_conflict, :default_values
128
+
129
+ def initialize(table_name, columns = [], values = [], rows: nil, on_conflict: nil, default_values: false)
130
+ super(:insert, table_name, columns)
131
+ @rows = rows || [values]
132
+ @values = @rows.first || []
133
+ @on_conflict = on_conflict
134
+ @default_values = default_values
135
+ end
135
136
  end
136
137
 
137
138
  class Update < Plan
@@ -154,12 +154,13 @@ module RubyDB
154
154
 
155
155
  def plan_insert(statement)
156
156
  Plan::Insert.new(
157
- statement.table,
158
- statement.columns,
159
- statement.values,
160
- rows: statement.rows,
161
- on_conflict: statement.on_conflict
162
- )
157
+ statement.table,
158
+ statement.columns,
159
+ statement.values,
160
+ rows: statement.rows,
161
+ on_conflict: statement.on_conflict,
162
+ default_values: statement.default_values?
163
+ )
163
164
  end
164
165
 
165
166
  def plan_update(statement)
@@ -186,10 +187,13 @@ module RubyDB
186
187
  plan
187
188
  end
188
189
 
189
- def plan_create_table(statement)
190
- columns = statement.columns.map do |col|
191
- Catalog::Column.new(col.name, col.type_class, **col.options)
192
- end
190
+ def plan_create_table(statement)
191
+ columns = statement.columns.map do |col|
192
+ options = col.options.dup
193
+ default = options[:default]
194
+ options[:default] = default.value if default.respond_to?(:value) && !default.is_a?(String)
195
+ Catalog::Column.new(col.name, col.type_class, **options)
196
+ end
193
197
 
194
198
  Plan::CreateTable.new(
195
199
  statement.name,
@@ -5,15 +5,17 @@ module RubyDB
5
5
  module AST
6
6
  # INSERT statement AST node
7
7
  class Insert < Node
8
- attr_reader :table, :columns, :values, :rows, :on_conflict
9
-
10
- def initialize(table, columns = [], values = [], rows: nil, on_conflict: nil, location: nil)
11
- super(location: location)
12
- @table = table
13
- @columns = columns
14
- @rows = rows || [values]
15
- @values = @rows.first || []
16
- @on_conflict = on_conflict
8
+ attr_reader :table, :columns, :values, :rows, :on_conflict
9
+ attr_reader :default_values
10
+
11
+ def initialize(table, columns = [], values = [], rows: nil, on_conflict: nil, default_values: false, location: nil)
12
+ super(location: location)
13
+ @table = table
14
+ @columns = columns
15
+ @rows = rows || [values]
16
+ @values = @rows.first || []
17
+ @on_conflict = on_conflict
18
+ @default_values = default_values
17
19
  end
18
20
 
19
21
  def accept(visitor)
@@ -24,8 +26,9 @@ module RubyDB
24
26
  Insert.new(
25
27
  @table,
26
28
  @columns.dup,
27
- @values.map(&:clone), rows: @rows.map { |row| row.map(&:clone) }, on_conflict: @on_conflict,
28
- location: @location
29
+ @values.map(&:clone), rows: @rows.map { |row| row.map(&:clone) }, on_conflict: @on_conflict,
30
+ default_values: @default_values,
31
+ location: @location
29
32
  )
30
33
  end
31
34
 
@@ -37,8 +40,12 @@ module RubyDB
37
40
  parts << "(#{@columns.join(", ")})"
38
41
  end
39
42
 
40
- parts << "VALUES"
41
- parts << @rows.map { |row| "(#{row.map(&:to_sql).join(", ")})" }.join(", ")
43
+ if @default_values
44
+ parts << "DEFAULT VALUES"
45
+ else
46
+ parts << "VALUES"
47
+ parts << @rows.map { |row| "(#{row.map(&:to_sql).join(", ")})" }.join(", ")
48
+ end
42
49
  parts << "ON CONFLICT DO NOTHING" if @on_conflict == :nothing
43
50
  if @on_conflict.is_a?(Hash) && @on_conflict[:action] == :update
44
51
  target = @on_conflict[:target].any? ? " (#{@on_conflict[:target].join(', ')})" : ""
@@ -56,9 +63,13 @@ module RubyDB
56
63
  end
57
64
 
58
65
  # Helper methods
59
- def has_columns?
60
- @columns.any?
61
- end
66
+ def has_columns?
67
+ @columns.any?
68
+ end
69
+
70
+ def default_values?
71
+ @default_values
72
+ end
62
73
 
63
74
  def value_count
64
75
  @values.size
@@ -539,21 +539,30 @@ module RubyDB
539
539
  expect(Token::Type::RPAREN)
540
540
  end
541
541
 
542
- expect(Token::Type::VALUES)
543
- rows = []
544
- loop do
545
- expect(Token::Type::LPAREN)
546
- values = []
547
- while true
548
- values << parse_expression
549
- break unless current_token&.type == Token::Type::COMMA
550
- advance
551
- end
552
- expect(Token::Type::RPAREN)
553
- rows << values
554
- break unless current_token&.type == Token::Type::COMMA
555
- advance
556
- end
542
+ default_values = false
543
+ if current_token&.type == Token::Type::DEFAULT
544
+ advance
545
+ expect(Token::Type::VALUES)
546
+ default_values = true
547
+ else
548
+ expect(Token::Type::VALUES)
549
+ end
550
+ rows = default_values ? [[]] : []
551
+ unless default_values
552
+ loop do
553
+ expect(Token::Type::LPAREN)
554
+ values = []
555
+ while true
556
+ values << parse_expression
557
+ break unless current_token&.type == Token::Type::COMMA
558
+ advance
559
+ end
560
+ expect(Token::Type::RPAREN)
561
+ rows << values
562
+ break unless current_token&.type == Token::Type::COMMA
563
+ advance
564
+ end
565
+ end
557
566
 
558
567
  on_conflict = nil
559
568
  if current_token&.type == Token::Type::ON
@@ -589,8 +598,9 @@ module RubyDB
589
598
  raise ParserError, "Expected NOTHING or UPDATE after ON CONFLICT DO"
590
599
  end
591
600
  end
592
- AST::Insert.new(table, columns, rows.first || [], rows: rows, on_conflict: on_conflict)
593
- end
601
+ AST::Insert.new(table, columns, rows.first || [], rows: rows, on_conflict: on_conflict,
602
+ default_values: default_values)
603
+ end
594
604
 
595
605
  def parse_update
596
606
  expect(Token::Type::UPDATE)
@@ -675,16 +675,32 @@ module RubyDB
675
675
  end
676
676
 
677
677
  # Row operations
678
- def insert_row(table_name, columns, values)
679
- ensure_writable!
680
- table_name = resolve_table_name(table_name)
681
- @lock.synchronize do
678
+ def insert_row(table_name, columns, values)
679
+ ensure_writable!
680
+ table_name = resolve_table_name(table_name)
681
+ @lock.synchronize do
682
682
  @stats[:row_inserts] += 1
683
683
 
684
- metadata = @table_metadata[table_name]
685
- raise DatabaseError, "Table '#{table_name}' does not exist" unless metadata
686
-
687
- # Rails and other SQL clients omit an INTEGER primary key on insert
684
+ metadata = @table_metadata[table_name]
685
+ raise DatabaseError, "Table '#{table_name}' does not exist" unless metadata
686
+
687
+ # SQL INSERT may omit columns entirely (DEFAULT VALUES) or omit
688
+ # only selected columns. Materialize declared defaults before
689
+ # constraint validation so NOT NULL defaults are valid and the
690
+ # physical row contains scalar values rather than AST wrappers.
691
+ if values.is_a?(Hash)
692
+ values = values.dup
693
+ columns.each do |column|
694
+ present = values.key?(column.name) || values.key?(column.name.to_sym)
695
+ next if present || !column.has_default?
696
+
697
+ default = column.default
698
+ default = default.value if default.respond_to?(:value)
699
+ values[column.name] = default
700
+ end
701
+ end
702
+
703
+ # Rails and other SQL clients omit an INTEGER primary key on insert
688
704
  # and expect the database to allocate it. Keep allocation in the
689
705
  # engine so embedded and server connections have identical behavior.
690
706
  if values.is_a?(Hash)
@@ -11,13 +11,13 @@ module RubyDB
11
11
  # - MAJOR: Incompatible API changes
12
12
  # - MINOR: Backwards-compatible new functionality
13
13
  # - PATCH: Backwards-compatible bug fixes
14
- VERSION = "0.1.0"
14
+ VERSION = "0.1.2"
15
15
 
16
16
  # Version components for easy access
17
17
  module Version
18
18
  MAJOR = 0
19
19
  MINOR = 1
20
- PATCH = 0
20
+ PATCH = 2
21
21
  PRE = nil # e.g., "alpha", "beta", "rc1"
22
22
 
23
23
  def self.to_s
@@ -30,4 +30,4 @@ module RubyDB
30
30
  version
31
31
  end
32
32
  end
33
- end
33
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubydb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aldane Hutchinson