activerecord-cockroachdb-adapter 0.2.3 → 5.2.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 +5 -5
- data/.gitignore +1 -0
- data/.gitmodules +0 -3
- data/CONTRIBUTING.md +25 -53
- data/Gemfile +58 -6
- data/README.md +293 -2
- data/Rakefile +17 -5
- data/activerecord-cockroachdb-adapter.gemspec +3 -6
- data/build/Dockerfile +1 -1
- data/build/teamcity-test.sh +17 -37
- data/docker.sh +1 -1
- data/lib/active_record/connection_adapters/cockroachdb/arel_tosql.rb +27 -0
- data/lib/active_record/connection_adapters/cockroachdb/attribute_methods.rb +28 -0
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +94 -0
- data/lib/active_record/connection_adapters/cockroachdb/column_methods.rb +53 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +102 -0
- data/lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb +121 -0
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +37 -0
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +23 -38
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +123 -40
- data/lib/active_record/connection_adapters/cockroachdb/setup.rb +19 -0
- data/lib/active_record/connection_adapters/cockroachdb/spatial_column_info.rb +44 -0
- data/lib/active_record/connection_adapters/cockroachdb/table_definition.rb +56 -0
- data/lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb +14 -16
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +218 -123
- metadata +18 -42
data/Rakefile
CHANGED
@@ -1,10 +1,22 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require_relative 'test/support/paths_cockroachdb'
|
4
|
+
require_relative 'test/support/rake_helpers'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
task test: ["test:cockroachdb"]
|
7
|
+
task default: [:test]
|
8
|
+
|
9
|
+
namespace :test do
|
10
|
+
Rake::TestTask.new("cockroachdb") do |t|
|
11
|
+
t.libs = ARTest::CockroachDB.test_load_paths
|
12
|
+
t.test_files = test_files
|
13
|
+
t.warning = !!ENV["WARNING"]
|
14
|
+
t.verbose = false
|
15
|
+
end
|
16
|
+
|
17
|
+
task "cockroachdb:env" do
|
18
|
+
ENV["ARCONN"] = "cockroachdb"
|
19
|
+
end
|
8
20
|
end
|
9
21
|
|
10
|
-
task :
|
22
|
+
task 'test:cockroachdb' => 'test:cockroachdb:env'
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "activerecord-cockroachdb-adapter"
|
7
|
-
spec.version = "
|
7
|
+
spec.version = "5.2.2"
|
8
8
|
spec.licenses = ["Apache-2.0"]
|
9
9
|
spec.authors = ["Cockroach Labs"]
|
10
10
|
spec.email = ["cockroach-db@googlegroups.com"]
|
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://github.com/cockroachdb/activerecord-cockroachdb-adapter"
|
15
15
|
|
16
16
|
spec.add_dependency "activerecord", "~> 5.2"
|
17
|
-
spec.add_dependency "pg", ">= 0.20"
|
17
|
+
spec.add_dependency "pg", ">= 0.20"
|
18
|
+
spec.add_dependency "rgeo-activerecord", "~> 7.0.0"
|
18
19
|
|
19
20
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
20
21
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
@@ -31,8 +32,4 @@ Gem::Specification.new do |spec|
|
|
31
32
|
spec.bindir = "exe"
|
32
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
34
|
spec.require_paths = ["lib"]
|
34
|
-
|
35
|
-
spec.add_development_dependency "bundler", "~> 1.14"
|
36
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
38
35
|
end
|
data/build/Dockerfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This Dockerfile extends the Examples-ORM testing image in order to
|
2
2
|
# install specific dependencies required for ActiveRecord tests.
|
3
3
|
|
4
|
-
FROM cockroachdb/
|
4
|
+
FROM cockroachdb/example-orms-builder:20200413-1918
|
5
5
|
|
6
6
|
# Native dependencies for libxml-ruby and sqlite3.
|
7
7
|
RUN apt-get update -y && apt-get install -y \
|
data/build/teamcity-test.sh
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
|
3
|
-
set -
|
3
|
+
set -euox pipefail
|
4
4
|
|
5
|
-
# Download CockroachDB
|
6
|
-
|
7
|
-
VERSION=v2.0-alpha.20171218
|
5
|
+
# Download CockroachDB
|
6
|
+
VERSION=v20.2.3
|
8
7
|
wget -qO- https://binaries.cockroachdb.com/cockroach-$VERSION.linux-amd64.tgz | tar xvz
|
9
8
|
readonly COCKROACH=./cockroach-$VERSION.linux-amd64/cockroach
|
10
9
|
|
11
10
|
# Make sure cockroach can be found on the path. This is required for the
|
12
11
|
# ActiveRecord Rakefile that rebuilds the test database.
|
13
|
-
export PATH
|
12
|
+
export PATH=./cockroach-$VERSION.linux-amd64/:$PATH
|
14
13
|
readonly urlfile=cockroach-url
|
15
14
|
|
16
15
|
run_cockroach() {
|
@@ -22,7 +21,7 @@ run_cockroach() {
|
|
22
21
|
cockroach quit --insecure || true
|
23
22
|
rm -rf cockroach-data
|
24
23
|
# Start CockroachDB.
|
25
|
-
cockroach start --insecure --host=localhost --listening-url-file="$urlfile" >/dev/null 2>&1 &
|
24
|
+
cockroach start-single-node --max-sql-memory=25% --cache=25% --insecure --host=localhost --spatial-libs=./cockroach-$VERSION.linux-amd64/lib --listening-url-file="$urlfile" >/dev/null 2>&1 &
|
26
25
|
# Ensure CockroachDB is stopped on script exit.
|
27
26
|
trap "echo 'Exit routine: Killing CockroachDB.' && kill -9 $! &> /dev/null" EXIT
|
28
27
|
# Wait until CockroachDB has started.
|
@@ -32,45 +31,26 @@ run_cockroach() {
|
|
32
31
|
echo "server not yet available; sleeping for $backoff seconds"
|
33
32
|
sleep $backoff
|
34
33
|
done
|
34
|
+
cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest;'
|
35
|
+
cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest2;'
|
36
|
+
cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;'
|
37
|
+
cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.histogram_collection.enabled = false;'
|
38
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING jobs.retention_time = '180s';"
|
35
39
|
}
|
36
40
|
|
37
|
-
# Target the Rails dependency file.
|
38
|
-
export BUNDLE_GEMFILE=$(pwd)/rails/Gemfile
|
39
|
-
|
40
41
|
# Install ruby dependencies.
|
42
|
+
gem install bundler:2.1.4
|
41
43
|
bundle install
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
# 'Install' our adapter. This involves symlinking it inside of
|
46
|
-
# ActiveRecord. Normally the adapter will transitively install
|
47
|
-
# ActiveRecord, but we need to execute tests from inside the Rails
|
48
|
-
# context so we cannot rely on that. We also need previous links to make
|
49
|
-
# tests idempotent.
|
50
|
-
rm -f rails/activerecord/lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
51
|
-
ln -s $(pwd)/lib/active_record/connection_adapters/cockroachdb_adapter.rb rails/activerecord/lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
52
|
-
rm -rf rails/activerecord/lib/active_record/connection_adapters/cockroachdb
|
53
|
-
ln -s $(pwd)/lib/active_record/connection_adapters/cockroachdb rails/activerecord/lib/active_record/connection_adapters/cockroachdb
|
45
|
+
run_cockroach
|
54
46
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
for TESTFILE in ${TESTS}; do
|
59
|
-
# Start CockroachDB
|
60
|
-
run_cockroach
|
61
|
-
# Run the tests.
|
62
|
-
echo "Rebuilding database"
|
63
|
-
(cd rails/activerecord && bundle exec rake db:cockroachdb:rebuild)
|
64
|
-
echo "Running test: $TESTFILE"
|
65
|
-
# Run the test. Continue testing even if this file fails.
|
66
|
-
if ! (cd rails/activerecord && bundle exec rake test:cockroachdb TESTFILES=$TESTFILE); then
|
67
|
-
echo "Test FAILED: $TESTFILE"
|
47
|
+
if ! (RUBYOPT="-W0" TESTOPTS="-v" bundle exec rake test); then
|
48
|
+
echo "Tests failed"
|
68
49
|
HAS_FAILED=1
|
69
|
-
|
70
|
-
echo "
|
50
|
+
else
|
51
|
+
echo "Tests passed"
|
71
52
|
HAS_FAILED=0
|
72
|
-
|
73
|
-
done
|
53
|
+
fi
|
74
54
|
|
75
55
|
# Attempt a clean shutdown for good measure. We'll force-kill in the
|
76
56
|
# exit trap if this script fails.
|
data/docker.sh
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RGeo
|
4
|
+
module ActiveRecord
|
5
|
+
##
|
6
|
+
# Extend rgeo-activerecord visitors to use PostGIS specific functionality
|
7
|
+
module SpatialToPostGISSql
|
8
|
+
def visit_in_spatial_context(node, collector)
|
9
|
+
# Use ST_GeomFromEWKT for EWKT geometries
|
10
|
+
if node.is_a?(String) && node =~ /SRID=[\d+]{0,};/
|
11
|
+
collector << "#{st_func('ST_GeomFromEWKT')}(#{quote(node)})"
|
12
|
+
else
|
13
|
+
super(node, collector)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RGeo::ActiveRecord::SpatialToSql.prepend RGeo::ActiveRecord::SpatialToPostGISSql
|
20
|
+
|
21
|
+
module Arel # :nodoc:
|
22
|
+
module Visitors # :nodoc:
|
23
|
+
class CockroachDB < PostgreSQL # :nodoc:
|
24
|
+
include RGeo::ActiveRecord::SpatialToSql
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module CockroachDB
|
3
|
+
module AttributeMethodsMonkeyPatch
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Filter out rowid so it doesn't get inserted by ActiveRecord. rowid is a
|
8
|
+
# column added by CockroachDB for tables that don't define primary keys.
|
9
|
+
# CockroachDB will automatically insert rowid values. See
|
10
|
+
# https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table.
|
11
|
+
def attributes_for_create(attribute_names)
|
12
|
+
super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Filter out rowid so it doesn't get updated by ActiveRecord. rowid is a
|
16
|
+
# column added by CockroachDB for tables that don't define primary keys.
|
17
|
+
# CockroachDB will automatically insert rowid values. See
|
18
|
+
# https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table.
|
19
|
+
def attributes_for_update(attribute_names)
|
20
|
+
super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Base
|
26
|
+
prepend CockroachDB::AttributeMethodsMonkeyPatch
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module CockroachDB
|
4
|
+
module PostgreSQLColumnMonkeyPatch
|
5
|
+
# most functions taken from activerecord-postgis-adapter spatial_column
|
6
|
+
# https://github.com/rgeo/activerecord-postgis-adapter/blob/master/lib/active_record/connection_adapters/postgis/spatial_column.rb
|
7
|
+
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil,
|
8
|
+
default_function = nil, collation = nil, comment = nil, cast_type = nil, opts = nil)
|
9
|
+
@sql_type_metadata = sql_type_metadata
|
10
|
+
@geographic = !!(sql_type_metadata.sql_type =~ /geography\(/i)
|
11
|
+
|
12
|
+
@cast_type = cast_type
|
13
|
+
@geographic = !!(sql_type_metadata.sql_type =~ /geography\(/i)
|
14
|
+
if opts
|
15
|
+
# This case comes from an entry in the geometry_columns table
|
16
|
+
set_geometric_type_from_name(opts[:type])
|
17
|
+
@srid = opts[:srid].to_i
|
18
|
+
@has_z = !!opts[:has_z]
|
19
|
+
@has_m = !!opts[:has_m]
|
20
|
+
elsif @geographic
|
21
|
+
# Geographic type information is embedded in the SQL type
|
22
|
+
@srid = 4326
|
23
|
+
@has_z = @has_m = false
|
24
|
+
build_from_sql_type(sql_type_metadata.sql_type)
|
25
|
+
elsif sql_type =~ /geography|geometry|point|linestring|polygon/i
|
26
|
+
build_from_sql_type(sql_type_metadata.sql_type)
|
27
|
+
elsif sql_type_metadata.sql_type =~ /geography|geometry|point|linestring|polygon/i
|
28
|
+
# A geometry column with no geometry_columns entry.
|
29
|
+
# @geometric_type = geo_type_from_sql_type(sql_type)
|
30
|
+
build_from_sql_type(sql_type_metadata.sql_type)
|
31
|
+
end
|
32
|
+
super(name, default, sql_type_metadata, null, table_name, default_function, collation, comment: comment)
|
33
|
+
if spatial?
|
34
|
+
if @srid
|
35
|
+
@limit = { srid: @srid, type: to_type_name(geometric_type) }
|
36
|
+
@limit[:has_z] = true if @has_z
|
37
|
+
@limit[:has_m] = true if @has_m
|
38
|
+
@limit[:geographic] = true if @geographic
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :geographic,
|
44
|
+
:geometric_type,
|
45
|
+
:has_m,
|
46
|
+
:has_z,
|
47
|
+
:srid
|
48
|
+
|
49
|
+
alias geographic? geographic
|
50
|
+
alias has_z? has_z
|
51
|
+
alias has_m? has_m
|
52
|
+
|
53
|
+
def limit
|
54
|
+
spatial? ? @limit : super
|
55
|
+
end
|
56
|
+
|
57
|
+
def spatial?
|
58
|
+
%i[geometry geography].include?(@sql_type_metadata.type)
|
59
|
+
end
|
60
|
+
|
61
|
+
def serial?
|
62
|
+
default_function == 'unique_rowid()'
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def set_geometric_type_from_name(name)
|
68
|
+
@geometric_type = RGeo::ActiveRecord.geometric_type_from_name(name) || RGeo::Feature::Geometry
|
69
|
+
end
|
70
|
+
|
71
|
+
def build_from_sql_type(sql_type)
|
72
|
+
geo_type, @srid, @has_z, @has_m = OID::Spatial.parse_sql_type(sql_type)
|
73
|
+
set_geometric_type_from_name(geo_type)
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_type_name(geometric_type)
|
77
|
+
name = geometric_type.type_name.underscore
|
78
|
+
case name
|
79
|
+
when 'point'
|
80
|
+
'st_point'
|
81
|
+
when 'polygon'
|
82
|
+
'st_polygon'
|
83
|
+
else
|
84
|
+
name
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class PostgreSQLColumn
|
91
|
+
prepend CockroachDB::PostgreSQLColumnMonkeyPatch
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module CockroachDB
|
6
|
+
module ColumnMethods
|
7
|
+
def spatial(name, options = {})
|
8
|
+
raise "You must set a type. For example: 't.spatial type: :st_point'" unless options[:type]
|
9
|
+
|
10
|
+
column(name, options[:type], **options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def geography(name, options = {})
|
14
|
+
column(name, :geography, **options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def geometry(name, options = {})
|
18
|
+
column(name, :geometry, **options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def geometry_collection(name, options = {})
|
22
|
+
column(name, :geometry_collection, **options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def line_string(name, options = {})
|
26
|
+
column(name, :line_string, **options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def multi_line_string(name, options = {})
|
30
|
+
column(name, :multi_line_string, **options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def multi_point(name, options = {})
|
34
|
+
column(name, :multi_point, **options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def multi_polygon(name, options = {})
|
38
|
+
column(name, :multi_polygon, **options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def st_point(name, options = {})
|
42
|
+
column(name, :st_point, **options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def st_polygon(name, options = {})
|
46
|
+
column(name, :st_polygon, **options)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
PostgreSQL::Table.include CockroachDB::ColumnMethods
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module CockroachDB
|
4
|
+
module DatabaseStatements
|
5
|
+
# Since CockroachDB will run all transactions with serializable isolation,
|
6
|
+
# READ UNCOMMITTED, READ COMMITTED, and REPEATABLE READ are all aliases
|
7
|
+
# for SERIALIZABLE. This lets the adapter support all isolation levels,
|
8
|
+
# but READ UNCOMMITTED has been removed from this list because the
|
9
|
+
# ActiveRecord transaction isolation test fails for READ UNCOMMITTED.
|
10
|
+
# See https://www.cockroachlabs.com/docs/v19.2/transactions.html#isolation-levels
|
11
|
+
def transaction_isolation_levels
|
12
|
+
{
|
13
|
+
read_committed: "READ COMMITTED",
|
14
|
+
repeatable_read: "REPEATABLE READ",
|
15
|
+
serializable: "SERIALIZABLE"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Overridden to avoid using transactions for schema creation.
|
20
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
21
|
+
fixture_inserts = build_fixture_statements(fixture_set)
|
22
|
+
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
|
23
|
+
statements = table_deletes + fixture_inserts
|
24
|
+
|
25
|
+
with_multi_statements do
|
26
|
+
disable_referential_integrity do
|
27
|
+
execute_batch(statements, "Fixtures Load")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def execute_batch(statements, name = nil)
|
34
|
+
statements.each do |statement|
|
35
|
+
execute(statement, name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
|
40
|
+
private_constant :DEFAULT_INSERT_VALUE
|
41
|
+
|
42
|
+
def default_insert_value(column)
|
43
|
+
DEFAULT_INSERT_VALUE
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_fixture_sql(fixtures, table_name)
|
47
|
+
columns = schema_cache.columns_hash(table_name)
|
48
|
+
|
49
|
+
values_list = fixtures.map do |fixture|
|
50
|
+
fixture = fixture.stringify_keys
|
51
|
+
|
52
|
+
unknown_columns = fixture.keys - columns.keys
|
53
|
+
if unknown_columns.any?
|
54
|
+
raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
|
55
|
+
end
|
56
|
+
|
57
|
+
columns.map do |name, column|
|
58
|
+
if fixture.key?(name)
|
59
|
+
type = lookup_cast_type_from_column(column)
|
60
|
+
with_yaml_fallback(type.serialize(fixture[name]))
|
61
|
+
else
|
62
|
+
default_insert_value(column)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
table = Arel::Table.new(table_name)
|
68
|
+
manager = Arel::InsertManager.new
|
69
|
+
manager.into(table)
|
70
|
+
|
71
|
+
if values_list.size == 1
|
72
|
+
values = values_list.shift
|
73
|
+
new_values = []
|
74
|
+
columns.each_key.with_index { |column, i|
|
75
|
+
unless values[i].equal?(DEFAULT_INSERT_VALUE)
|
76
|
+
new_values << values[i]
|
77
|
+
manager.columns << table[column]
|
78
|
+
end
|
79
|
+
}
|
80
|
+
values_list << new_values
|
81
|
+
else
|
82
|
+
columns.each_key { |column| manager.columns << table[column] }
|
83
|
+
end
|
84
|
+
|
85
|
+
manager.values = manager.create_values_list(values_list)
|
86
|
+
manager.to_sql
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_fixture_statements(fixture_set)
|
90
|
+
fixture_set.map do |table_name, fixtures|
|
91
|
+
next if fixtures.empty?
|
92
|
+
build_fixture_sql(fixtures, table_name)
|
93
|
+
end.compact
|
94
|
+
end
|
95
|
+
|
96
|
+
def with_multi_statements
|
97
|
+
yield
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|