cassandra_migrations 0.0.1.pre3 → 0.0.1.pre4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/cassandra_migrations/cassandra/keyspace_operations.rb +33 -0
- data/lib/cassandra_migrations/cassandra/queries.rb +47 -0
- data/lib/cassandra_migrations/cassandra.rb +45 -84
- data/lib/cassandra_migrations/config.rb +24 -0
- data/lib/cassandra_migrations/{cassandra/errors.rb → errors.rb} +2 -2
- data/lib/cassandra_migrations/{cassandra/migrator.rb → migrator.rb} +16 -8
- data/lib/cassandra_migrations/railtie/initializer.rb +24 -11
- data/lib/cassandra_migrations/railtie/tasks.rake +11 -11
- data/lib/cassandra_migrations.rb +4 -4
- data/spec/cassandra_migrations/cassandra_spec.rb +9 -9
- metadata +14 -11
- data/lib/cassandra_migrations/cassandra/query.rb +0 -44
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CassandraMigrations
|
4
|
+
module Cassandra
|
5
|
+
module KeyspaceOperations
|
6
|
+
|
7
|
+
def create_keyspace!
|
8
|
+
begin
|
9
|
+
execute(
|
10
|
+
"CREATE KEYSPACE #{Config.keyspace} \
|
11
|
+
WITH replication = { \
|
12
|
+
'class':'#{Config.replication['class']}', \
|
13
|
+
'replication_factor': #{Config.replication['replication_factor']} \
|
14
|
+
}"
|
15
|
+
)
|
16
|
+
use(Config.keyspace)
|
17
|
+
rescue Exception => exception
|
18
|
+
drop_keyspace!
|
19
|
+
raise exception
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def drop_keyspace!
|
24
|
+
begin
|
25
|
+
execute("DROP KEYSPACE #{Config.keyspace}")
|
26
|
+
rescue Cql::QueryError
|
27
|
+
raise Errors::UnexistingKeyspaceError, keyspace
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CassandraMigrations
|
4
|
+
module Cassandra
|
5
|
+
module Queries
|
6
|
+
|
7
|
+
def write!(table, hash)
|
8
|
+
columns = []
|
9
|
+
values = []
|
10
|
+
|
11
|
+
hash.each do |k,v|
|
12
|
+
columns << k.to_s
|
13
|
+
values << (v.is_a?(String) ? "'#{v.to_s}'" : v.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
execute("INSERT INTO #{table} (#{columns.join(', ')}) VALUES (#{values.join(', ')})")
|
17
|
+
end
|
18
|
+
|
19
|
+
def select(table, options={})
|
20
|
+
query_string = "SELECT #{options[:projection] || '*'} FROM #{table}"
|
21
|
+
|
22
|
+
if options[:selection]
|
23
|
+
query_string << " WHERE #{options[:selection]}"
|
24
|
+
end
|
25
|
+
|
26
|
+
if options[:order_by]
|
27
|
+
query_string << " ORDER BY #{options[:order_by]}"
|
28
|
+
end
|
29
|
+
|
30
|
+
if options[:limit]
|
31
|
+
query_string << " LIMIT #{options[:limit]}"
|
32
|
+
end
|
33
|
+
|
34
|
+
execute(query_string)
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete!(table, selection, options={})
|
38
|
+
execute("DELETE #{options[:projection]} FROM #{table} WHERE #{selection}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def truncate!(table)
|
42
|
+
execute("TRUNCATE #{table}")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -2,102 +2,63 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'cql'
|
5
|
-
require 'cassandra_migrations/cassandra/
|
6
|
-
require 'cassandra_migrations/cassandra/
|
7
|
-
require 'cassandra_migrations/cassandra/migrator'
|
5
|
+
require 'cassandra_migrations/cassandra/queries'
|
6
|
+
require 'cassandra_migrations/cassandra/keyspace_operations'
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
|
9
|
+
module CassandraMigrations
|
10
|
+
module Cassandra
|
11
|
+
extend Queries
|
12
|
+
extend KeyspaceOperations
|
14
13
|
|
15
|
-
|
16
|
-
connect_to_server unless client
|
14
|
+
mattr_accessor :client
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
use(
|
21
|
-
rescue Cql::QueryError # keyspace does not exist
|
22
|
-
raise Errors::UnexistingKeyspaceError, config['keyspace']
|
16
|
+
def self.start!
|
17
|
+
# setup keyspace use
|
18
|
+
use(Config.keyspace)
|
23
19
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
start!
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.shutdown!
|
33
|
-
if client
|
34
|
-
client.close
|
20
|
+
|
21
|
+
def self.restart!
|
22
|
+
raise Errors::ClientNotStartedError unless client
|
23
|
+
|
24
|
+
client.close if client && client.connected?
|
35
25
|
self.client = nil
|
26
|
+
start!
|
36
27
|
end
|
37
|
-
|
38
|
-
self.config = nil
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.create_keyspace!
|
42
|
-
connect_to_server unless client
|
43
28
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
'replication_factor': #{config['replication']['replication_factor']} \
|
50
|
-
}"
|
51
|
-
)
|
52
|
-
use(config['keyspace'])
|
53
|
-
execute("CREATE TABLE metadata (data_name varchar PRIMARY KEY, data_value varchar)")
|
54
|
-
write("metadata", {:data_name => 'version', :data_value => '0'})
|
55
|
-
rescue Exception => exception
|
56
|
-
drop!
|
57
|
-
raise exception
|
29
|
+
def self.shutdown!
|
30
|
+
raise Errors::ClientNotStartedError unless client
|
31
|
+
|
32
|
+
client.close if client.connected?
|
33
|
+
self.client = nil
|
58
34
|
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.drop!
|
62
|
-
connect_to_server unless client
|
63
35
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
36
|
+
def self.use(keyspace)
|
37
|
+
connect_to_server unless client
|
38
|
+
|
39
|
+
begin
|
40
|
+
client.use(keyspace)
|
41
|
+
rescue Cql::QueryError # keyspace does not exist
|
42
|
+
raise Errors::UnexistingKeyspaceError, keyspace
|
43
|
+
end
|
68
44
|
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.use(keyspace)
|
72
|
-
raise Errors::ClientNotStartedError unless client
|
73
|
-
client.use(keyspace)
|
74
|
-
end
|
75
45
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def self.connect_to_server
|
84
|
-
load_config
|
46
|
+
def self.execute(cql)
|
47
|
+
connect_to_server unless client
|
48
|
+
client.execute(cql)
|
49
|
+
end
|
85
50
|
|
86
|
-
|
51
|
+
private
|
87
52
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
begin
|
98
|
-
self.config = YAML.load_file(Rails.root.join("config", "cassandra.yml"))[Rails.env]
|
99
|
-
rescue Errno::ENOENT
|
100
|
-
raise Errors::MissingConfigurationError
|
53
|
+
def self.connect_to_server
|
54
|
+
Rails.logger.try(:info, "Connecting to Cassandra on #{Config.host}:#{Config.port}")
|
55
|
+
|
56
|
+
begin
|
57
|
+
self.client = Cql::Client.new(:host => Config.host, :port => Config.port)
|
58
|
+
client.connect
|
59
|
+
rescue Cql::Io::ConnectionError => e
|
60
|
+
raise Errors::ConnectionError, e.message
|
61
|
+
end
|
101
62
|
end
|
102
63
|
end
|
103
|
-
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CassandraMigrations
|
4
|
+
module Config
|
5
|
+
|
6
|
+
mattr_accessor :config
|
7
|
+
|
8
|
+
def self.method_missing(method_sym, *arguments, &block)
|
9
|
+
load_config unless config
|
10
|
+
config[method_sym.to_s]
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def self.load_config
|
16
|
+
begin
|
17
|
+
self.config = YAML.load_file(Rails.root.join("config", "cassandra.yml"))[Rails.env]
|
18
|
+
rescue Errno::ENOENT
|
19
|
+
raise Errors::MissingConfigurationError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
module CassandraMigrations
|
3
|
+
module CassandraMigrations
|
4
4
|
module Migrator
|
5
5
|
|
6
|
-
|
6
|
+
METADATA_TABLE = 'cassandra_migrations_metadata'
|
7
|
+
|
8
|
+
def self.up_to_latest!
|
7
9
|
current_version = read_current_version
|
8
10
|
|
9
11
|
new_migrations = get_all_migration_names.sort.select do |migration_name|
|
@@ -17,7 +19,7 @@ module CassandraMigrations::Cassandra
|
|
17
19
|
new_migrations.size
|
18
20
|
end
|
19
21
|
|
20
|
-
def self.rollback(count=1)
|
22
|
+
def self.rollback!(count=1)
|
21
23
|
current_version = read_current_version
|
22
24
|
|
23
25
|
executed_migrations = get_all_migration_names.sort.reverse.select do |migration_name|
|
@@ -39,7 +41,13 @@ module CassandraMigrations::Cassandra
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def self.read_current_version
|
42
|
-
|
44
|
+
begin
|
45
|
+
Cassandra.select(METADATA_TABLE, :selection => "data_name='version'", :projection => 'data_value').first['data_value'].to_i
|
46
|
+
rescue Cql::QueryError # table cassandra_migrations_metadata does not exist
|
47
|
+
Cassandra.execute("CREATE TABLE #{METADATA_TABLE} (data_name varchar PRIMARY KEY, data_value varchar)")
|
48
|
+
Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => '0'})
|
49
|
+
return 0
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
private
|
@@ -51,7 +59,7 @@ private
|
|
51
59
|
get_class_from_migration_name(migration_name).up
|
52
60
|
|
53
61
|
# update version
|
54
|
-
|
62
|
+
Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => get_version_from_migration_name(migration_name).to_s})
|
55
63
|
end
|
56
64
|
|
57
65
|
def self.down(migration_name, previous_migration_name=nil)
|
@@ -62,9 +70,9 @@ private
|
|
62
70
|
|
63
71
|
# downgrade version
|
64
72
|
if previous_migration_name
|
65
|
-
|
73
|
+
Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => get_version_from_migration_name(previous_migration_name).to_s})
|
66
74
|
else
|
67
|
-
|
75
|
+
Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => '0'})
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
@@ -80,4 +88,4 @@ private
|
|
80
88
|
migration_name.match(/([0-9]{14})_.+\.rb$/).captures.first.to_i
|
81
89
|
end
|
82
90
|
end
|
83
|
-
end
|
91
|
+
end
|
@@ -1,17 +1,30 @@
|
|
1
1
|
# encoding : utf-8
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
3
|
+
# In production (when Passenger is used with smart spawn), many ruby processes are created
|
4
|
+
# by forking the original spawner. Since the child process is a different process, it shares
|
5
|
+
# no memory with its father. Because of that we have to connect to cassandra again.
|
6
|
+
# It is also common that file descriptors are unintentionally shared when the process forks,
|
7
|
+
# that's why we go through the safe path and check if the client exists in order to restart it
|
8
|
+
# (production tests have shown that the client is nil when forked)
|
7
9
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# More explanations in: http://www.modrails.com/documentation/Users%20guide%20Apache.html#spawning_methods_explained
|
11
|
+
|
12
|
+
module CassandraMigrations
|
13
|
+
|
14
|
+
if defined?(PhusionPassenger)
|
15
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
16
|
+
if forked
|
17
|
+
if Cassandra.client
|
18
|
+
Rails.logger.info "Passenger process forked: reconnecting to Cassandra..."
|
19
|
+
Cassandra.restart!
|
20
|
+
else
|
21
|
+
Rails.logger.info "Passenger process forked: connecting to Cassandra..."
|
22
|
+
Cassandra.start!
|
23
|
+
end
|
24
|
+
end
|
13
25
|
end
|
26
|
+
else
|
27
|
+
Cassandra.start!
|
14
28
|
end
|
15
|
-
|
16
|
-
CassandraMigrations::Cassandra.start!
|
29
|
+
|
17
30
|
end
|
@@ -10,26 +10,26 @@ namespace :cassandra do
|
|
10
10
|
task :create do
|
11
11
|
begin
|
12
12
|
CassandraMigrations::Cassandra.start!
|
13
|
-
puts "Keyspace #{CassandraMigrations::
|
14
|
-
rescue CassandraMigrations::
|
13
|
+
puts "Keyspace #{CassandraMigrations::Config.keyspace} already exists!"
|
14
|
+
rescue CassandraMigrations::Errors::UnexistingKeyspaceError
|
15
15
|
CassandraMigrations::Cassandra.create_keyspace!
|
16
|
-
puts "Created keyspace #{CassandraMigrations::
|
16
|
+
puts "Created keyspace #{CassandraMigrations::Config.keyspace}"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
desc 'Drop keyspace in config/cassandra.yml for the current environment'
|
21
21
|
task :drop do
|
22
22
|
begin
|
23
|
-
CassandraMigrations::Cassandra.
|
24
|
-
puts "Dropped keyspace #{CassandraMigrations::
|
25
|
-
rescue CassandraMigrations::
|
26
|
-
puts "Keyspace #{CassandraMigrations::
|
23
|
+
CassandraMigrations::Cassandra.drop_keyspace!
|
24
|
+
puts "Dropped keyspace #{CassandraMigrations::Config.keyspace}"
|
25
|
+
rescue CassandraMigrations::Errors::UnexistingKeyspaceError
|
26
|
+
puts "Keyspace #{CassandraMigrations::Config.keyspace} does not exist... cannot be dropped"
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
desc 'Migrate the keyspace to the latest version'
|
31
31
|
task :migrate => :start do
|
32
|
-
migrations_up_count = CassandraMigrations::
|
32
|
+
migrations_up_count = CassandraMigrations::Migrator.up_to_latest!
|
33
33
|
|
34
34
|
if migrations_up_count == 0
|
35
35
|
puts "Already up-to-date"
|
@@ -40,9 +40,9 @@ namespace :cassandra do
|
|
40
40
|
|
41
41
|
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n)'
|
42
42
|
task :rollback => :start do
|
43
|
-
steps = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
43
|
+
steps = (ENV['STEP'] ? ENV['STEP'].to_i : 1)
|
44
44
|
|
45
|
-
migrations_down_count = CassandraMigrations::
|
45
|
+
migrations_down_count = CassandraMigrations::Migrator.rollback!(steps)
|
46
46
|
|
47
47
|
if steps == migrations_down_count
|
48
48
|
puts "Rolled back #{steps} version(s)."
|
@@ -68,7 +68,7 @@ namespace :cassandra do
|
|
68
68
|
|
69
69
|
desc 'Retrieves the current schema version number'
|
70
70
|
task :version => :start do
|
71
|
-
puts "Current version: #{
|
71
|
+
puts "Current version: #{CassandraMigrations::Migrator.read_current_version}"
|
72
72
|
end
|
73
73
|
|
74
74
|
end
|
data/lib/cassandra_migrations.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
end
|
4
|
-
|
1
|
+
require 'cassandra_migrations/config'
|
2
|
+
require 'cassandra_migrations/errors'
|
5
3
|
require 'cassandra_migrations/cassandra'
|
4
|
+
require 'cassandra_migrations/migrator'
|
5
|
+
|
6
6
|
require 'cassandra_migrations/railtie' if defined?(Rails)
|
@@ -14,7 +14,7 @@ describe CassandraMigrations::Cassandra do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
after do
|
17
|
-
CassandraMigrations::Cassandra.shutdown!
|
17
|
+
CassandraMigrations::Cassandra.shutdown! if CassandraMigrations::Cassandra.client
|
18
18
|
end
|
19
19
|
|
20
20
|
describe ".start!" do
|
@@ -45,18 +45,16 @@ describe CassandraMigrations::Cassandra do
|
|
45
45
|
|
46
46
|
it "should use host and port configurations to create cassandra client" do
|
47
47
|
cql_client_mock = Cql::Client.new
|
48
|
-
cql_client_mock.should_receive(:
|
48
|
+
cql_client_mock.should_receive(:connect)
|
49
|
+
cql_client_mock.stub(:use)
|
49
50
|
Cql::Client.should_receive(:new).with(:host => '127.0.0.1', :port => 9042).and_return(cql_client_mock)
|
50
51
|
|
51
|
-
|
52
|
-
CassandraMigrations::Cassandra.start!
|
53
|
-
rescue
|
54
|
-
end
|
52
|
+
CassandraMigrations::Cassandra.start!
|
55
53
|
end
|
56
54
|
|
57
55
|
it "should raise exception if not able to connect to cassandra host" do
|
58
56
|
cql_client_mock = Cql::Client.new
|
59
|
-
cql_client_mock.stub(:
|
57
|
+
cql_client_mock.stub(:connect).and_raise Cql::Io::ConnectionError
|
60
58
|
Cql::Client.stub(:new).and_return cql_client_mock
|
61
59
|
|
62
60
|
expect do
|
@@ -68,7 +66,9 @@ describe CassandraMigrations::Cassandra do
|
|
68
66
|
CassandraMigrations::Cassandra.should_receive(:use).with('cassandra_migrations_development')
|
69
67
|
CassandraMigrations::Cassandra.start!
|
70
68
|
end
|
71
|
-
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.use' do
|
72
72
|
it "should raise exception if configured keyspace does not exist" do
|
73
73
|
expect do
|
74
74
|
CassandraMigrations::Cassandra.start!
|
@@ -85,4 +85,4 @@ describe CassandraMigrations::Cassandra do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
end
|
88
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassandra_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.
|
4
|
+
version: 0.0.1.pre4
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.0.0.
|
21
|
+
version: 1.0.0.pre7
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.0.0.
|
29
|
+
version: 1.0.0.pre7
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,17 +99,20 @@ extensions: []
|
|
99
99
|
extra_rdoc_files: []
|
100
100
|
files:
|
101
101
|
- lib/cassandra_migrations.rb
|
102
|
-
- lib/cassandra_migrations/
|
103
|
-
- lib/cassandra_migrations/cassandra/query.rb
|
104
|
-
- lib/cassandra_migrations/cassandra/errors.rb
|
105
|
-
- lib/cassandra_migrations/railtie/tasks.rake
|
106
|
-
- lib/cassandra_migrations/railtie/initializer.rb
|
102
|
+
- lib/cassandra_migrations/migrator.rb
|
107
103
|
- lib/cassandra_migrations/cassandra.rb
|
108
104
|
- lib/cassandra_migrations/railtie.rb
|
109
|
-
-
|
105
|
+
- lib/cassandra_migrations/cassandra/keyspace_operations.rb
|
106
|
+
- lib/cassandra_migrations/cassandra/queries.rb
|
107
|
+
- lib/cassandra_migrations/config.rb
|
108
|
+
- lib/cassandra_migrations/railtie/initializer.rb
|
109
|
+
- lib/cassandra_migrations/railtie/tasks.rake
|
110
|
+
- lib/cassandra_migrations/errors.rb
|
110
111
|
- spec/cassandra_migrations_spec.rb
|
112
|
+
- spec/cassandra_migrations/cassandra_spec.rb
|
111
113
|
homepage: https://github.com/hsgubert/cassandra_migrations
|
112
|
-
licenses:
|
114
|
+
licenses:
|
115
|
+
- MIT
|
113
116
|
post_install_message:
|
114
117
|
rdoc_options: []
|
115
118
|
require_paths:
|
@@ -133,5 +136,5 @@ signing_key:
|
|
133
136
|
specification_version: 3
|
134
137
|
summary: Cassandra schema management for a multi-environment developer.
|
135
138
|
test_files:
|
136
|
-
- spec/cassandra_migrations/cassandra_spec.rb
|
137
139
|
- spec/cassandra_migrations_spec.rb
|
140
|
+
- spec/cassandra_migrations/cassandra_spec.rb
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module CassandraMigrations::Cassandra
|
4
|
-
module Query
|
5
|
-
|
6
|
-
def write(table, hash)
|
7
|
-
columns = []
|
8
|
-
values = []
|
9
|
-
|
10
|
-
hash.each do |k,v|
|
11
|
-
columns << k.to_s
|
12
|
-
values << "'#{v.to_s}'"
|
13
|
-
end
|
14
|
-
|
15
|
-
execute("INSERT INTO #{table} (#{columns.join(', ')}) VALUES (#{values.join(', ')})")
|
16
|
-
end
|
17
|
-
|
18
|
-
def select(table, options={})
|
19
|
-
query_string = "SELECT #{options[:projection] || '*'} FROM #{table}"
|
20
|
-
|
21
|
-
if options[:selection]
|
22
|
-
query_string << " WHERE #{options[:selection]}"
|
23
|
-
end
|
24
|
-
|
25
|
-
if options[:order_by]
|
26
|
-
query_string << " ORDER BY #{options[:order_by]}"
|
27
|
-
end
|
28
|
-
|
29
|
-
if options[:limit]
|
30
|
-
query_string << " LIMIT #{options[:limit]}"
|
31
|
-
end
|
32
|
-
|
33
|
-
execute(query_string)
|
34
|
-
end
|
35
|
-
|
36
|
-
def delete(table, selection, options={})
|
37
|
-
execute("DELETE #{options[:projection]} FROM #{table} WHERE #{selection}")
|
38
|
-
end
|
39
|
-
|
40
|
-
def truncate(table)
|
41
|
-
execute("TRUNCATE #{table}")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|