arc 0.0.1.2 → 0.0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -36,6 +36,9 @@ namespace :test do
36
36
  task :docs do
37
37
  `rspec spec -f h > doc/spec.html`
38
38
  end
39
+ task :wip do
40
+ system "rspec spec --tag wip"
41
+ end
39
42
  end
40
43
 
41
44
  #example use of passing arguments to rake
@@ -15,6 +15,8 @@ module Arc
15
15
  boolean: 'boolean',
16
16
  bit: 'boolean',
17
17
  float: 'float' ,
18
+ text: 'string' ,
19
+ bytea: 'binary' ,
18
20
  }
19
21
 
20
22
  CAST_METHODS = Hash.new do |cast_methods, key|
@@ -13,11 +13,24 @@ module Arc
13
13
  def fetch_item name
14
14
  MysqlTable.new name, @data_store
15
15
  end
16
+
17
+ def execute_ddl ddl
18
+ case ddl
19
+ when Array
20
+ ddl = ddl.select do |stmt|
21
+ !stmt.nil? && !stmt.empty? && !stmt == "\n"
22
+ end
23
+ ddl.each { |s| @data_store.execute "#{s}" }
24
+ when String
25
+ execute_ddl ddl.split(';')
26
+ end
27
+ end
28
+
16
29
  end
17
30
 
18
31
  class MysqlTable < Table
19
32
  def raw_column_data
20
- @data_store.read("SHOW FULL FIELDS FROM superheros").each do |r|
33
+ @data_store.read("show fields from #{self.name}").each do |r|
21
34
  r
22
35
  end
23
36
  end
@@ -25,8 +38,8 @@ module Arc
25
38
  raw_column_data.map {|c| c[:Field].to_sym }
26
39
  end
27
40
  def fetch_item name
28
- return {} unless keys.include? name.to_sym
29
41
  c = raw_column_data.find{|c| c[:Field] == name.to_s}
42
+ throw "Column '#{name}' does not exist" unless keys.include? name.to_sym
30
43
  MysqlColumn.new @data_store,{
31
44
  name: c[:Field],
32
45
  allows_null: c[:Null] == "YES",
@@ -42,6 +55,7 @@ module Arc
42
55
  :int => :integer,
43
56
  }
44
57
  def type
58
+ @stype ||= ''
45
59
  @type ||= begin
46
60
  type_key = @stype.downcase.gsub(/\([\d,]*\)/, '').to_sym
47
61
  TYPES[type_key] || type_key
@@ -9,7 +9,7 @@ module Arc::DataStores
9
9
  class MysqlDataStore < AbstractDataStore
10
10
 
11
11
  def read query
12
- execute(query)
12
+ execute(query).entries
13
13
  end
14
14
 
15
15
  def create sql
@@ -25,6 +25,11 @@ module Arc::DataStores
25
25
  def destroy sql
26
26
  execute sql
27
27
  end
28
+
29
+ def quote_column_name table
30
+ "`#{table}`"
31
+ end
32
+ alias :quote_column :quote_column_name
28
33
 
29
34
  def execute query
30
35
  with_store do |store|
@@ -60,7 +60,7 @@ module Arc
60
60
  class PostgresColumn < Column
61
61
  def type
62
62
  return :varchar if @stype =~ /character varying/
63
- return :time if @stype =~ /timestamp/
63
+ return :time if @stype =~ /time/
64
64
  @stype.to_sym
65
65
  end
66
66
  end
@@ -1,3 +1,3 @@
1
1
  module Arc
2
- VERSION = "0.0.1.2"
2
+ VERSION = "0.0.1.3"
3
3
  end
@@ -1,76 +1,93 @@
1
1
  require 'spec_helper'
2
-
2
+ require 'pp'
3
3
  module Arc
4
4
  module DataStores
5
5
  describe 'The data store crud operations' do
6
-
7
- describe '#create' do
8
- it 'creates a new record' do
9
- ArcTest.with_store do |store|
10
- query = "SELECT * FROM superheros WHERE name = 'green hornet'"
11
- result = store.read query
12
- result.size.should == 0
13
-
14
- store.create "INSERT INTO superheros (name) VALUES('green hornet');"
15
- store.read(query).size.should == 1
16
-
17
- #cleanup
18
- store.destroy "DELETE FROM superheros where name = 'green hornet'"
19
- end
6
+ #convenience method for building a tree of arel values
7
+ def values_array table_name, hash
8
+ hash.keys.map do |attr|
9
+ [@tables[table_name][attr], hash[attr]]
20
10
  end
21
-
22
- it 'returns the record with a populated primary key' do
23
- ArcTest.with_store do |store|
24
- result = store.create "INSERT INTO superheros (name) VALUES('green lantern')"
25
- result[:id].should_not be_nil
26
- result[:name].should == 'green lantern'
27
- #cleanup
28
- store.destroy "DELETE FROM superheros where name = 'green lantern'"
29
- end
11
+ end
12
+
13
+ #grab a superhero record by name
14
+ def get_hero(hero_name)
15
+ query = @tables[:superheros]
16
+ .project('*')
17
+ .where(@tables[:superheros][:name].eq(hero_name))
18
+ .to_sql
19
+ @store.read query
20
+ end
21
+
22
+ before :each do
23
+ ArcTest.with_store do |store|
24
+ Arel::Table.engine = store
25
+ load "spec/support/seed.rb"
30
26
  end
27
+ @tables = Hash.new { |hash, key| hash[key] = Arel::Table.new key }
28
+ @store = Arel::Table.engine
31
29
  end
32
30
 
33
- describe '#read' do
34
- it 'reads existing data' do
35
- heros = ['superman', 'batman', 'spiderman']
36
- query = "SELECT * FROM superheros"
37
-
38
- ArcTest.with_store do |store|
39
- result = store.read query
40
- result.size.should == 3
41
- result.each do |h|
42
- h.should be_a(Hash)
43
- heros.should include(h[:name])
44
- end
45
- end
31
+ describe '#create and #read' do
32
+ before :each do
33
+ properties = {
34
+ :name => "green hornet",
35
+ :born_on => Time.now,
36
+ :photo => "hello",
37
+ :created_at => Time.now
38
+ }
39
+ im = Arel::InsertManager.new Arel::Table.engine
40
+ im.insert values_array(:superheros, properties)
41
+ @result = @store.create im.to_sql
42
+ end
43
+
44
+ it 'creates a new record' do
45
+ query = @tables[:superheros]
46
+ .project('*')
47
+ .where(@tables[:superheros][:name].eq('green hornet'))
48
+ .to_sql
49
+ result = @store.read query
50
+ result[0][:name].should == 'green hornet'
51
+ end
52
+
53
+ it 'returns the record with a populated primary key' do
54
+ @result[:id].should_not be_nil
55
+ @result[:name].should == 'green hornet'
46
56
  end
57
+
47
58
  end
48
59
 
49
60
  describe '#update' do
50
61
  it 'updates a record and returns the updated record' do
51
- ArcTest.with_store do |store|
52
- query = "UPDATE superheros SET name = 'wussy' WHERE name = 'batman'"
53
- result = store.update query
54
- batman = store.read "SELECT * from superheros WHERE name = 'batman'"
55
- batman.size.should == 0
56
- batman.should be_a(Enumerable)
57
- batman = store.read "SELECT * from superheros WHERE name = 'wussy'"
58
- batman.first[:name].should == 'wussy'
59
- end
62
+ properties = {:name => 'batman'}
63
+ um = Arel::UpdateManager.new @store
64
+ um.table @tables[:superheros]
65
+ um.set(values_array(:superheros, properties))
66
+ .where(@tables[:superheros][:name].eq('megaman'))
67
+ query = um.to_sql
68
+ result = @store.update query
69
+
70
+ megaman = get_hero('megaman')
71
+ megaman.size.should == 0
72
+ megaman.should be_a(Enumerable)
73
+
74
+ batman = get_hero('batman')
75
+ batman.size.should == 1
76
+ batman.first[:name].should == 'batman'
60
77
  end
61
78
  end
62
79
 
63
80
  describe '#destroy' do
64
81
  it 'deletes a record' do
65
- ArcTest.with_store do |store|
66
- query = "SELECT * FROM superheros WHERE name = 'batman'"
67
- batman = store.read query
68
- batman.first[:name].should == 'batman'
69
- store.destroy "DELETE FROM superheros WHERE name = 'batman'"
70
- batman = store.read query
71
- batman.size.should == 0
72
- batman.should be_a(Enumerable)
73
- end
82
+ delete = Arel::DeleteManager.new @store
83
+ delete
84
+ .from(@tables[:superheros])
85
+ .where(@tables[:superheros][:name].eq('superman'))
86
+ @store.destroy delete.to_sql
87
+ superman = get_hero('superman')
88
+ superman.size.should == 0
89
+ superman.size.should == 0
90
+ superman.should be_a(Enumerable)
74
91
  end
75
92
  end
76
93
 
@@ -6,7 +6,9 @@ module Arc
6
6
  describe "All the Schemas!" do
7
7
  it 'lists the table names' do
8
8
  ArcTest.with_store do |store|
9
- store.schema.table_names.should == [:superheros]
9
+ [:superheros, :powers, :superheros_powers].each do |t|
10
+ store.schema.table_names.should include(t)
11
+ end
10
12
  end
11
13
  end
12
14
 
@@ -2,6 +2,15 @@ require 'spec_helper'
2
2
  require 'arc/data_stores/mysql/store'
3
3
 
4
4
  describe Arc::DataStores::MysqlDataStore do
5
+ describe '#quote_table_name', :wip => true do
6
+ store = Arc::DataStores::MysqlDataStore.new ArcTest.config[:mysql]
7
+ store.quote_table_name('my-table').should == "`my-table`"
8
+ end
9
+ describe '#quote_column_name', :wip => true do
10
+ store = Arc::DataStores::MysqlDataStore.new ArcTest.config[:mysql]
11
+ store.quote_column_name('my-column').should == "`my-column`"
12
+ end
13
+
5
14
  describe "#schema" do
6
15
  it 'is an instance of Arc::DataStores::MysqlSchema' do
7
16
  store = Arc::DataStores::MysqlDataStore.new ArcTest.config[:mysql]
@@ -8,4 +8,14 @@ describe Arc::DataStores::PostgresDataStore do
8
8
  store.schema.should be_a(Arc::DataStores::ObjectDefinitions::PostgresSchema)
9
9
  end
10
10
  end
11
+ describe Arc::DataStores::ObjectDefinitions::PostgresColumn, :wip => true do
12
+ it 'returns a time type' do
13
+ c = Arc::DataStores::ObjectDefinitions::PostgresColumn.new(nil,
14
+ :type => "time without time zone"
15
+ )
16
+ stype = c.instance_variable_get :@stype
17
+ stype.should == "time without time zone"
18
+ c.type.should == :time
19
+ end
20
+ end
11
21
  end
@@ -26,6 +26,9 @@ module Arc
26
26
  quoter.quote("'").should == "''''"
27
27
  quoter.quote("my%String", String).should == "'my%String'"
28
28
  end
29
+ it 'quotes text' do
30
+ quoter.quote("hello world", "text").should == "'hello world'"
31
+ end
29
32
  it 'quotes a date object' do
30
33
  date = Date.today
31
34
  fmt = '%Y-%m-%d'
@@ -1,10 +1,22 @@
1
+ DROP TABLE IF EXISTS superheros;
1
2
  CREATE TABLE superheros (
2
3
  id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
3
- name VARCHAR(256) NOT NULL
4
+ name VARCHAR(256) NOT NULL,
5
+ born_on DATE NOT NULL,
6
+ photo BINARY NULL,
7
+ created_at TIME NOT NULL
8
+ );
9
+
10
+ DROP TABLE IF EXISTS powers;
11
+ CREATE TABLE powers (
12
+ id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
13
+ name VARCHAR(256) NOT NULL,
14
+ description TEXT NOT NULL
15
+ );
16
+
17
+ DROP TABLE IF EXISTS superheros_powers;
18
+ CREATE TABLE superheros_powers(
19
+ id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
20
+ superhero_id INTEGER NOT NULL,
21
+ power_id INTEGER NOT NULL
4
22
  );
5
- INSERT INTO superheros(name)
6
- VALUES('superman');
7
- INSERT INTO superheros(name)
8
- VALUES('spiderman');
9
- INSERT INTO superheros(name)
10
- VALUES('batman');
@@ -1,12 +1,26 @@
1
1
  BEGIN TRANSACTION;
2
+
3
+ DROP TABLE IF EXISTS superheros;
2
4
  CREATE TABLE superheros (
3
5
  id SERIAL PRIMARY KEY,
4
- name VARCHAR(256) NOT NULL
6
+ name VARCHAR(256) NOT NULL,
7
+ born_on DATE NOT NULL,
8
+ photo bytea NULL,
9
+ created_at TIME NOT NULL
5
10
  );
6
- INSERT INTO superheros(name)
7
- VALUES('superman');
8
- INSERT INTO superheros(name)
9
- VALUES('spiderman');
10
- INSERT INTO superheros(name)
11
- VALUES('batman');
11
+
12
+ DROP TABLE IF EXISTS powers;
13
+ CREATE TABLE powers (
14
+ id SERIAL PRIMARY KEY,
15
+ name VARCHAR(256) NOT NULL,
16
+ description TEXT NOT NULL
17
+ );
18
+
19
+ DROP TABLE IF EXISTS superheros_powers;
20
+ CREATE TABLE superheros_powers(
21
+ id SERIAL PRIMARY KEY,
22
+ superhero_id INTEGER NOT NULL,
23
+ power_id INTEGER NOT NULL
24
+ );
25
+
12
26
  COMMIT;
@@ -1,12 +1,26 @@
1
1
  BEGIN TRANSACTION;
2
+
3
+ DROP TABLE IF EXISTS superheros;
2
4
  CREATE TABLE superheros (
3
5
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
- name VARCHAR(256) NOT NULL
6
+ name VARCHAR(256) NOT NULL,
7
+ born_on DATE NOT NULL,
8
+ photo BINARY NULL,
9
+ created_at TIME NOT NULL
5
10
  );
6
- INSERT INTO superheros(name)
7
- VALUES('superman');
8
- INSERT INTO superheros(name)
9
- VALUES('spiderman');
10
- INSERT INTO superheros(name)
11
- VALUES('batman');
11
+
12
+ DROP TABLE IF EXISTS powers;
13
+ CREATE TABLE powers (
14
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
15
+ name VARCHAR(256) NOT NULL,
16
+ description TEXT NOT NULL
17
+ );
18
+
19
+ DROP TABLE IF EXISTS superheros_powers;
20
+ CREATE TABLE superheros_powers(
21
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
22
+ superhero_id INTEGER NOT NULL,
23
+ power_id INTEGER NOT NULL
24
+ );
25
+
12
26
  COMMIT;
@@ -0,0 +1,57 @@
1
+
2
+ tables = Hash.new do |hash, key|
3
+ hash[key] = Arel::Table.new key
4
+ end
5
+ file_root = File.expand_path("../", __FILE__)
6
+ data = {
7
+ :superheros =>
8
+ [
9
+ {
10
+ :name => 'superman',
11
+ :born_on => Time.now,
12
+ :photo => 'file',#File.read("#{file_root}/resources/superman.gif"),
13
+ :created_at => Time.now
14
+ },
15
+ {
16
+ :name => 'ironman',
17
+ :born_on => Time.now,
18
+ :photo => 'file',#File.read("#{file_root}/resources/ironman.gif"),
19
+ :created_at => Time.now
20
+ },
21
+ {
22
+ :name => 'megaman',
23
+ :born_on => Time.now,
24
+ :photo => 'file',#File.read("#{file_root}/resources/megaman.jpg"),
25
+ :created_at => Time.now
26
+ }
27
+ ],
28
+ :powers =>
29
+ [
30
+ {
31
+ :name => 'flight',
32
+ :description => "The ability to levitate in and move through the air.",
33
+ },
34
+ {
35
+ :name => 'money',
36
+ :description => 'The ability to act like the billionaire owner of apple computer.'
37
+ },
38
+ {
39
+ :name => 'ice blaster',
40
+ :description => 'Not really a power, but hey. It shoots ice.'
41
+ }
42
+ ]
43
+ }
44
+
45
+ data.each_pair do |name, tuples|
46
+ table = tables[name]
47
+ delete = Arel::DeleteManager.new Arel::Table.engine
48
+ Arel::Table.engine.destroy delete.from(table).to_sql
49
+ tuples.each do |tuple|
50
+ stmt = Arel::InsertManager.new Arel::Table.engine
51
+ values = tuple.keys.map do |key|
52
+ [table[key], tuple[key]]
53
+ end
54
+ stmt.insert(values)
55
+ Arel::Table.engine.create stmt.to_sql
56
+ end
57
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.2
4
+ version: 0.0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-22 00:00:00.000000000Z
12
+ date: 2011-12-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: agent-q
16
- requirement: &70171055331800 !ruby/object:Gem::Requirement
16
+ requirement: &70338722320520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70171055331800
24
+ version_requirements: *70338722320520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: arel
27
- requirement: &70171055331380 !ruby/object:Gem::Requirement
27
+ requirement: &70338722319980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70171055331380
35
+ version_requirements: *70338722319980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: pg
38
- requirement: &70171055330960 !ruby/object:Gem::Requirement
38
+ requirement: &70338722319560 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70171055330960
46
+ version_requirements: *70338722319560
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sqlite3
49
- requirement: &70171055330540 !ruby/object:Gem::Requirement
49
+ requirement: &70338722319020 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70171055330540
57
+ version_requirements: *70338722319020
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: mysql2
60
- requirement: &70171055330100 !ruby/object:Gem::Requirement
60
+ requirement: &70338722318480 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70171055330100
68
+ version_requirements: *70338722318480
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70171055329640 !ruby/object:Gem::Requirement
71
+ requirement: &70338722294800 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70171055329640
79
+ version_requirements: *70338722294800
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov
82
- requirement: &70171055329140 !ruby/object:Gem::Requirement
82
+ requirement: &70338722294240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70171055329140
90
+ version_requirements: *70338722294240
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: ruby-debug
93
- requirement: &70171055328680 !ruby/object:Gem::Requirement
93
+ requirement: &70338722293820 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70171055328680
101
+ version_requirements: *70338722293820
102
102
  description: Compatible with mysql, sqlite, and postgres
103
103
  email:
104
104
  - jacob.s.morris@gmail.com
@@ -139,13 +139,17 @@ files:
139
139
  - spec/quoting_spec.rb
140
140
  - spec/spec_helper.rb
141
141
  - spec/support/config.yml
142
+ - spec/support/resources/ironman.gif
143
+ - spec/support/resources/megaman.jpg
142
144
  - spec/support/resources/rails.png
145
+ - spec/support/resources/superman.gif
143
146
  - spec/support/schemas/drop_mysql.sql
144
147
  - spec/support/schemas/drop_postgres.sql
145
148
  - spec/support/schemas/drop_sqlite.sql
146
149
  - spec/support/schemas/mysql.sql
147
150
  - spec/support/schemas/postgres.sql
148
151
  - spec/support/schemas/sqlite.sql
152
+ - spec/support/seed.rb
149
153
  homepage: ''
150
154
  licenses: []
151
155
  post_install_message:
@@ -184,10 +188,14 @@ test_files:
184
188
  - spec/quoting_spec.rb
185
189
  - spec/spec_helper.rb
186
190
  - spec/support/config.yml
191
+ - spec/support/resources/ironman.gif
192
+ - spec/support/resources/megaman.jpg
187
193
  - spec/support/resources/rails.png
194
+ - spec/support/resources/superman.gif
188
195
  - spec/support/schemas/drop_mysql.sql
189
196
  - spec/support/schemas/drop_postgres.sql
190
197
  - spec/support/schemas/drop_sqlite.sql
191
198
  - spec/support/schemas/mysql.sql
192
199
  - spec/support/schemas/postgres.sql
193
200
  - spec/support/schemas/sqlite.sql
201
+ - spec/support/seed.rb