Skip to content

Commit 269001e

Browse files
BuonOmorafiss
authored andcommitted
feat: support sql load
1 parent 002b097 commit 269001e

File tree

4 files changed

+103
-4
lines changed

4 files changed

+103
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Ongoing
44

5+
- Add support for sql load in rake tasks (#275).
56
- Add support for sql dump in rake tasks (#273).
67
- Add support for table optimize hints (#266).
78

lib/active_record/connection_adapters/cockroachdb/database_tasks.rb

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,49 @@ def structure_dump(filename, extra_flags=nil)
4545
end
4646

4747
def structure_load(filename, extra_flags=nil)
48-
raise "db:structure:load is unimplemented. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/2"
48+
if extra_flags
49+
raise "No flag supported yet, please raise an issue if needed. " \
50+
"https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/new"
51+
end
52+
53+
run_cmd("cockroach", ["sql", "--set", "errexit=false", "--file", filename], "loading")
54+
end
55+
56+
private
57+
58+
# Adapted from https://github.com/rails/rails/blob/a5fc471b3/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb#L106.
59+
# Using https://www.cockroachlabs.com/docs/stable/connection-parameters.html#additional-connection-parameters.
60+
def cockroach_env
61+
usr_pwd = ""
62+
if configuration_hash[:username]
63+
usr_pwd += configuration_hash[:username].to_s
64+
if configuration_hash[:password]
65+
usr_pwd += ":"
66+
usr_pwd += configuration_hash[:password].to_s
67+
end
68+
usr_pwd += "@"
69+
end
70+
71+
port = ""
72+
port = ":#{configuration_hash[:port]}" if configuration_hash[:port]
73+
74+
params = %i(sslmode sslrootcert sslcert sslkey).filter_map do |key|
75+
"#{key}=#{configuration_hash[key]}" if configuration_hash[key]
76+
end.join("&")
77+
params = "?#{params}" unless params.empty?
78+
79+
url = "postgres://#{usr_pwd}#{db_config.host}#{port}/#{db_config.database}#{params}"
80+
81+
{
82+
# NOTE: sslmode in the url will take precedence over this setting, hence
83+
# we don't need to conditionally set it.
84+
"COCKROACH_INSECURE" => "true",
85+
"COCKROACH_URL" => url
86+
}
4987
end
88+
# The `#run_cmd` method use `psql_env` to set environments variables.
89+
# We override it with cockroach env variables.
90+
alias_method :psql_env, :cockroach_env
5091
end
5192
end
5293
end

test/cases/tasks/cockroachdb_rake_test.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,62 @@ def test_structure_dump
5454
refute read.include?("CREATE TABLE public.accounts ("), "\"accounts\" table should be ignored"
5555
end
5656
end
57+
58+
class CockroachDBStructureLoadTest < ActiveRecord::TestCase
59+
def setup
60+
@configuration = {
61+
adapter: "cockroachdb",
62+
database: "my-app-db",
63+
host: "localhost"
64+
}
65+
end
66+
67+
def test_structure_load
68+
filename = "awesome-file.sql"
69+
assert_called_with(
70+
Kernel,
71+
:system,
72+
[
73+
{"COCKROACH_INSECURE"=>"true", "COCKROACH_URL"=>"postgres://localhost/my-app-db"},
74+
"cockroach", "sql", "--set", "errexit=false", "--file", filename
75+
],
76+
returns: true
77+
) do
78+
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
79+
end
80+
end
81+
82+
def test_url_generation
83+
assert_correct_url @configuration.merge(
84+
%i(sslmode sslrootcert sslcert sslkey).to_h { [_1, "v#{_1}"] }
85+
), "postgres://localhost/my-app-db?sslmode=vsslmode&sslrootcert=vsslrootcert&sslcert=vsslcert&sslkey=vsslkey"
86+
assert_correct_url @configuration.merge({
87+
username: "root",
88+
port: 1234
89+
}), "postgres://root@localhost:1234/my-app-db"
90+
assert_correct_url @configuration.merge({
91+
username: "root",
92+
password: "secret"
93+
}), "postgres://root:secret@localhost/my-app-db"
94+
end
95+
96+
private
97+
98+
# Verify that given a config we generate the expected connection URL,
99+
# and that if we parse it again, we get the same config. Except the
100+
# `adapter` key, that'll changed to postgresql as the url given to
101+
# `cockroach sql` must start with the `postrges://` scheme.
102+
def assert_correct_url(config, expected_url)
103+
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new("default_env", "primary", config)
104+
task_chief = ActiveRecord::ConnectionAdapters::CockroachDB::DatabaseTasks.new(db_config)
105+
generated_url = task_chief.send(:cockroach_env)["COCKROACH_URL"]
106+
107+
conf_from_generated_url = ActiveRecord::Base.
108+
configurations.
109+
resolve(generated_url).
110+
configuration_hash
111+
assert_equal expected_url, generated_url
112+
assert_equal config.except(:adapter), conf_from_generated_url.except(:adapter)
113+
end
114+
end
57115
end

test/support/rake_helpers.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ def test_files
1717
ar_test_files = ar_test_files.
1818
split(',').
1919
map { |file| File.join ARTest::CockroachDB.root_activerecord, file.strip }.
20-
then { _1.prepend(COCKROACHDB_TEST_HELPER) unless _1.empty? }.
21-
prepend(COCKROACHDB_TEST_HELPER)
20+
tap { _1.prepend(COCKROACHDB_TEST_HELPER) unless _1.empty? }
2221

2322
cr_test_files = cr_test_files.split(',').map(&:strip)
2423

@@ -28,7 +27,7 @@ def test_files
2827
def all_test_files
2928
activerecord_test_files = Dir.
3029
glob("#{ARTest::CockroachDB.root_activerecord}/test/cases/**/*_test.rb").
31-
reject { _1.match?(%r(/adapters/(?:mysql2|sqlite3)/) }.
30+
reject { _1.match?(%r(/adapters/(?:mysql2|sqlite3)/)) }.
3231
prepend(COCKROACHDB_TEST_HELPER)
3332

3433
cockroachdb_test_files = Dir.glob('test/cases/**/*_test.rb')

0 commit comments

Comments
 (0)