sql_wrangler 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/sql_wrangler.rb CHANGED
@@ -1,70 +1,72 @@
1
1
  require 'sqlite3'
2
2
 
3
3
  module SqlWrangler
4
-
4
+
5
5
  class SqlConnection
6
-
7
- def query(sql_string)
8
- Query.new self, sql_string
6
+
7
+ def query(sql_string, params={})
8
+ Query.new(self, sql_string, params)
9
9
  end
10
-
10
+
11
11
  end
12
-
12
+
13
13
  class SqLiteConnection < SqlConnection
14
-
14
+
15
15
  def initialize(db_path)
16
16
  @db = SQLite3::Database.new db_path
17
17
  end
18
-
19
- def execute_sql(sql_string)
20
- @db.execute2(sql_string)
18
+
19
+ def execute_sql(sql_string, params={})
20
+ @db.execute2(sql_string, params)
21
21
  end
22
22
 
23
23
  def command(sql_string)
24
- @db.execute(sql_string)
24
+ @db.execute_batch(sql_string)
25
25
  end
26
26
 
27
27
  def close
28
28
  @db.close
29
29
  end
30
-
30
+
31
31
  end
32
-
32
+
33
33
  class Query
34
-
34
+
35
35
  attr_reader :sql_string
36
36
  attr_reader :groupings
37
37
  attr_reader :conn
38
-
39
- def initialize(conn, sql_string)
38
+ attr_accessor :params
39
+
40
+ def initialize(conn, sql_string, params={})
40
41
  @conn = conn
41
42
  @sql_string = sql_string
42
43
  @groupings = []
44
+ @params = params
43
45
  end
44
-
46
+
45
47
  def execute
46
- raw_result = @conn.execute_sql(@sql_string)
48
+ raw_result = @conn.execute_sql(@sql_string, @params)
47
49
  init_groups_for_execution raw_result[0]
48
50
  return format_query_result(raw_result)
49
51
  end
50
-
52
+
51
53
  def format_query_result(raw_result)
52
54
  formatted_result = []
53
55
  columns_by_index = get_columns_by_index raw_result[0]
54
-
56
+
55
57
  raw_result[1,raw_result.length-1].each do |raw_row|
56
58
  merge_row raw_row, @groupings, formatted_result, columns_by_index
57
59
  end
58
-
60
+
59
61
  return formatted_result
60
62
  end
61
-
63
+
62
64
  def get_columns_by_index columns
63
65
  columns_by_index = {}
64
66
  (0..columns.length-1).each { |i| columns_by_index[i] = columns[i] }
65
67
  return columns_by_index
66
68
  end
67
-
69
+
68
70
  def init_groups_for_execution columns
69
71
  used_indexes = []
70
72
  @groupings.each do |group|
@@ -80,9 +82,9 @@ module SqlWrangler
80
82
  end
81
83
  end
82
84
  end
83
-
85
+
84
86
  def merge_row(row, groups, grouped_data, columns_by_index)
85
-
87
+
86
88
  if not @groupings.any?
87
89
  flat_row = {}
88
90
  columns_by_index.each { |index, column| flat_row[column] = row[index] }
@@ -112,7 +114,7 @@ module SqlWrangler
112
114
  end
113
115
 
114
116
  end
115
-
117
+
116
118
  def get_existing_grouped_row grouped_vals, grouped_data
117
119
  grouped_data.each do |grouped_row|
118
120
  if not grouped_vals.keys.any? { |key| grouped_vals[key] != grouped_row[key] }
@@ -121,29 +123,29 @@ module SqlWrangler
121
123
  end
122
124
  return nil
123
125
  end
124
-
126
+
125
127
  def group_by columns, options = {}
126
128
  new_grouping = QueryGrouping.new(options[:into], columns)
127
129
  new_grouping.level = @groupings.length
128
130
  @groupings << new_grouping
129
131
  return self
130
132
  end
131
-
133
+
132
134
  end
133
-
135
+
134
136
  class QueryGrouping
135
-
137
+
136
138
  attr_reader :name
137
139
  attr_reader :columns
138
140
  attr_accessor :content_indexes
139
141
  attr_accessor :group_indexes
140
142
  attr_accessor :level
141
-
143
+
142
144
  def initialize(name, columns)
143
145
  @name = name
144
146
  @columns = columns
145
147
  end
146
-
148
+
147
149
  end
148
-
149
- end
150
+
151
+ end
@@ -2,15 +2,15 @@ require 'fas_test'
2
2
  require './lib/sql_wrangler'
3
3
 
4
4
  class SqLiteConnectionTests < FasTest::TestClass
5
-
5
+
6
6
  def class_setup
7
7
  @conn = SqlWrangler::SqLiteConnection.new ":memory:"
8
8
  end
9
-
9
+
10
10
  def class_teardown
11
11
  @conn.close
12
12
  end
13
-
13
+
14
14
  def test__command
15
15
  begin
16
16
  @conn.command("CREATE TABLE users (id int PRIMARY KEY, username VARCHAR(100), password VARCHAR(100))")
@@ -21,26 +21,26 @@ class SqLiteConnectionTests < FasTest::TestClass
21
21
  @conn.command("DROP TABLE users")
22
22
  end
23
23
  end
24
-
24
+
25
25
  def test__query__without_executing_it
26
26
  query = @conn.query("SELECT * FROM users")
27
27
  assert_equal("SELECT * FROM users", query.sql_string)
28
28
  end
29
-
29
+
30
30
  end
31
31
 
32
32
  class QueryTests < FasTest::TestClass
33
-
33
+
34
34
  def class_setup
35
35
  @conn = SqlWrangler::SqLiteConnection.new ":memory:"
36
36
  @conn.execute_sql("CREATE TABLE users (username VARCHAR(100), password VARCHAR(100))")
37
37
  @conn.execute_sql("CREATE TABLE groups (group_name VARCHAR(100))")
38
38
  @conn.execute_sql("CREATE TABLE users_groups (username VARCHAR(100), group_name VARCHAR(100))")
39
-
39
+
40
40
  @conn.execute_sql("create table articles (id int primary key, title varchar(100), content varchar(100), author varchar(100))")
41
41
  @conn.execute_sql("create table comments (id int primary key, content text, article_id int)")
42
42
  end
43
-
43
+
44
44
  def test_setup
45
45
  @conn.execute_sql("INSERT INTO users VALUES ('username1', 'password1');")
46
46
  @conn.execute_sql("INSERT INTO users VALUES ('username2', 'password2');")
@@ -49,7 +49,7 @@ class QueryTests < FasTest::TestClass
49
49
  @conn.execute_sql("INSERT INTO users_groups VALUES ('username1', 'group one')")
50
50
  @conn.execute_sql("INSERT INTO users_groups VALUES ('username1', 'group two')")
51
51
  @conn.execute_sql("INSERT INTO users_groups VALUES ('username2', 'group one')")
52
-
52
+
53
53
  @conn.execute_sql("insert into articles values (1, 'article1', 'content1', 'username1')")
54
54
  @conn.execute_sql("insert into comments values (1, 'comment on article1 #1', 1)")
55
55
  @conn.execute_sql("insert into comments values (2, 'comment on article1 #2', 1)")
@@ -62,11 +62,11 @@ class QueryTests < FasTest::TestClass
62
62
  @conn.execute_sql("delete from articles")
63
63
  @conn.execute_sql("delete from comments")
64
64
  end
65
-
65
+
66
66
  def class_teardown
67
67
  @conn.close
68
68
  end
69
-
69
+
70
70
  def test__execute__has_correct_values_on_simple_query
71
71
  result = @conn.query("SELECT * FROM users").execute
72
72
  assert_equal(2, result.length)
@@ -75,16 +75,39 @@ class QueryTests < FasTest::TestClass
75
75
  assert_equal("username2", result[1]['username'])
76
76
  assert_equal("password2", result[1]['password'])
77
77
  end
78
-
78
+
79
79
  def test__execute__has_correct_columns_on_simple_query
80
80
  first = @conn.query("SELECT * FROM users").execute[0]
81
81
  assert_true(first.keys.any? { |m| m == 'username' })
82
82
  assert_true(first.keys.any? { |m| m == 'password' })
83
83
  end
84
-
84
+
85
+ def test__execute__works_with_param_setter
86
+ query = @conn.query("select password from users where username=:username")
87
+ query.params = {:username => 'username1'}
88
+ result = query.execute
89
+ assert_equal(1, result.length)
90
+ assert_equal('password1', result[0]['password'])
91
+ end
92
+
93
+ def test__execute__works_with_params_in_ctor
94
+ query = @conn.query("select password from users where username=:username", :username => 'username1')
95
+ result = query.execute
96
+ assert_equal(1, result.length)
97
+ assert_equal('password1', result[0]['password'])
98
+ end
99
+
100
+ def test__execute__works_with_param_modification
101
+ query = @conn.query("select password from users where username=:username")
102
+ query.params[:username] = 'username1'
103
+ result = query.execute
104
+ assert_equal(1, result.length)
105
+ assert_equal('password1', result[0]['password'])
106
+ end
107
+
85
108
  def test__execute__works_with_a_more_complex_query
86
109
  result = @conn.query("
87
- select u.username, g.group_name
110
+ select u.username, g.group_name
88
111
  from groups g
89
112
  inner join users_groups ug on ug.group_name = g.group_name
90
113
  inner join users u on u.username = ug.username
@@ -97,10 +120,10 @@ class QueryTests < FasTest::TestClass
97
120
  assert_equal("username2", result[2]["username"])
98
121
  assert_equal("group one", result[2]["group_name"])
99
122
  end
100
-
123
+
101
124
  def test__execute__works_with_a_simple_grouping
102
125
  result = @conn.query("
103
- select u.username, g.group_name
126
+ select u.username, g.group_name
104
127
  from groups g
105
128
  inner join users_groups ug on ug.group_name = g.group_name
106
129
  inner join users u on u.username = ug.username
@@ -114,10 +137,10 @@ class QueryTests < FasTest::TestClass
114
137
  assert_equal(1, result[1]["users"].length)
115
138
  assert_equal("username1", result[1]["users"][0]["username"])
116
139
  end
117
-
140
+
118
141
  def test__group__modifies_query_object_correctly_with_single_grouping
119
142
  query = @conn.query("
120
- select u.username, g.group_name
143
+ select u.username, g.group_name
121
144
  from groups g
122
145
  inner join users_groups ug on ug.group_name = g.group_name
123
146
  inner join users u on u.username = ug.username
@@ -127,7 +150,7 @@ class QueryTests < FasTest::TestClass
127
150
  assert_equal(1, query.groupings[0].columns.length)
128
151
  assert_equal("group_name", query.groupings[0].columns[0])
129
152
  end
130
-
153
+
131
154
  def test__execute__works_with_multi_level_grouping
132
155
  result = @conn.query("
133
156
  select u.username, g.group_name, a.title, a.content article_content, c.id comment_id, c.content comment_content
@@ -141,16 +164,16 @@ class QueryTests < FasTest::TestClass
141
164
  .group_by(["username"], :into => "articles") \
142
165
  .group_by(["article_content", "title"], :into => "comments") \
143
166
  .execute
144
-
167
+
145
168
  assert_equal(2, result.length)
146
169
  assert_equal("group one", result[0]["group_name"])
147
170
  assert_equal(2, result[0]["users"].length)
148
171
  assert_equal("username1", result[0]["users"][0]["username"])
149
-
172
+
150
173
  assert_equal(1, result[0]["users"][0]["articles"].length)
151
174
  assert_equal("article1", result[0]["users"][0]["articles"][0]["title"])
152
175
  assert_equal("content1", result[0]["users"][0]["articles"][0]["article_content"])
153
-
176
+
154
177
  assert_equal(2, result[0]["users"][0]["articles"][0]["comments"].length)
155
178
  assert_equal(1, result[0]["users"][0]["articles"][0]["comments"][0]["comment_id"])
156
179
  assert_equal("comment on article1 #1", result[0]["users"][0]["articles"][0]["comments"][0]["comment_content"])
@@ -158,11 +181,11 @@ class QueryTests < FasTest::TestClass
158
181
  assert_equal("comment on article1 #2", result[0]["users"][0]["articles"][0]["comments"][1]["comment_content"])
159
182
  assert_equal("username2", result[0]["users"][1]["username"])
160
183
  assert_equal(0, result[0]["users"][1]["articles"].length)
161
-
184
+
162
185
  assert_equal("group two", result[1]["group_name"])
163
186
  assert_equal(1, result[1]["users"].length)
164
187
  assert_equal("username1", result[1]["users"][0]["username"])
165
188
  assert_equal(1, result[1]["users"][0]["articles"].length)
166
189
  end
167
-
168
- end
190
+
191
+ end
metadata CHANGED
@@ -1,8 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql_wrangler
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.3
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
6
10
  platform: ruby
7
11
  authors:
8
12
  - Graeme Hill
@@ -10,7 +14,7 @@ autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
16
 
13
- date: 2011-03-01 00:00:00 -08:00
17
+ date: 2011-10-15 00:00:00 -07:00
14
18
  default_executable:
15
19
  dependencies: []
16
20
 
@@ -38,21 +42,23 @@ rdoc_options: []
38
42
  require_paths:
39
43
  - lib
40
44
  required_ruby_version: !ruby/object:Gem::Requirement
41
- none: false
42
45
  requirements:
43
46
  - - ">="
44
47
  - !ruby/object:Gem::Version
48
+ segments:
49
+ - 0
45
50
  version: "0"
46
51
  required_rubygems_version: !ruby/object:Gem::Requirement
47
- none: false
48
52
  requirements:
49
53
  - - ">="
50
54
  - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
51
57
  version: "0"
52
58
  requirements: []
53
59
 
54
60
  rubyforge_project:
55
- rubygems_version: 1.5.2
61
+ rubygems_version: 1.3.6
56
62
  signing_key:
57
63
  specification_version: 3
58
64
  summary: A simple ORM alternative that makes it easier to deal with SQL queries in ruby.