sql_wrangler 0.0.3 → 1.0.0

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.
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.