sequel_mapper 0.0.1

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.
@@ -0,0 +1,194 @@
1
+ class SequelMapper::MockSequel
2
+ def initialize(relations)
3
+ @relations = {}
4
+
5
+ relations.each do |table_name|
6
+ @relations[table_name] = Relation.new(self, [])
7
+ end
8
+
9
+ @reads, @writes, @deletes = 0, 0, 0
10
+ end
11
+
12
+ attr_reader :relations
13
+ private :relations
14
+
15
+ def [](table_name)
16
+ @relations.fetch(table_name)
17
+ end
18
+
19
+ def log_read
20
+ @reads += 1
21
+ end
22
+
23
+ def log_write
24
+ @writes += 1
25
+ end
26
+
27
+ def log_delete
28
+ @deletes += 1
29
+ end
30
+
31
+ def read_count
32
+ @reads
33
+ end
34
+
35
+ def write_count
36
+ @writes
37
+ end
38
+
39
+ def delete_count
40
+ @deletes
41
+ end
42
+
43
+ class Query
44
+ def initialize(criteria: {}, order: [], reverse: false, &block)
45
+ if block
46
+ raise NotImplementedError.new("Block filtering not implemented")
47
+ end
48
+
49
+ @criteria = criteria
50
+ @order_columns = order
51
+ @reverse_order = reverse
52
+ end
53
+
54
+ attr_reader :criteria, :order_columns
55
+
56
+ def where(new_criteria, &block)
57
+ self.class.new(
58
+ criteria: criteria.merge(new_criteria),
59
+ order: order,
60
+ reverse: reverse,
61
+ &block
62
+ )
63
+ end
64
+
65
+ def order(columns)
66
+ self.class.new(
67
+ criteria: criteria,
68
+ order: columns,
69
+ )
70
+ end
71
+
72
+ def reverse
73
+ self.class.new(
74
+ criteria: criteria,
75
+ order: order_columns,
76
+ reverse: true,
77
+ )
78
+ end
79
+
80
+ def reverse_order?
81
+ !!@reverse_order
82
+ end
83
+ end
84
+
85
+ class Relation
86
+ include Enumerable
87
+
88
+ def initialize(database, all_rows, applied_query: Query.new)
89
+ @database = database
90
+ @all_rows = all_rows
91
+ @applied_query = applied_query
92
+ end
93
+
94
+ attr_reader :database, :all_rows, :applied_query
95
+ private :database, :all_rows, :applied_query
96
+
97
+ def where(criteria, &block)
98
+ new_with_query(Query.new(criteria: criteria, &block))
99
+ end
100
+
101
+ def order(columns)
102
+ new_with_query(applied_query.order(columns))
103
+ end
104
+
105
+ def reverse
106
+ @applied_query = @applied_query.reverse
107
+ end
108
+
109
+ def to_a
110
+ database.log_read
111
+
112
+ matching_rows
113
+ end
114
+
115
+ def each(&block)
116
+ puts "iterating over #{matching_rows}"
117
+ database.log_read
118
+
119
+ matching_rows.each(&block)
120
+ end
121
+
122
+ def delete
123
+ database.log_delete
124
+
125
+ matching_rows.each do |row_to_delete|
126
+ all_rows.delete(row_to_delete)
127
+ end
128
+ end
129
+
130
+ def insert(new_row)
131
+ database.log_write
132
+
133
+ all_rows.push(new_row)
134
+ end
135
+
136
+ def update(attrs)
137
+ database.log_write
138
+
139
+ # No need to get the rows from the canonical relation as the hashes can
140
+ # just be mutated in plaace.
141
+ matching_rows.each do |row|
142
+ attrs.each do |k, v|
143
+ row[k] = v
144
+ end
145
+ end
146
+ end
147
+
148
+ def empty?
149
+ database.log_read
150
+
151
+ matching_rows.empty?
152
+ end
153
+
154
+ private
155
+
156
+ def matching_rows
157
+ apply_sort(
158
+ equality_filter(all_rows, applied_query.criteria),
159
+ applied_query.order_columns,
160
+ applied_query.reverse_order?,
161
+ )
162
+ end
163
+
164
+ def apply_sort(rows, order_columns, reverse_order)
165
+ sorted_rows = rows.sort_by{ |row|
166
+ order_columns.map { |col| row.fetch(col) }
167
+ }
168
+
169
+ if reverse_order
170
+ sorted_rows.reverse
171
+ else
172
+ sorted_rows
173
+ end
174
+ end
175
+
176
+ def equality_filter(rows, criteria)
177
+ rows.select { |row|
178
+ criteria.all? { |k, v|
179
+ if v.is_a?(Enumerable)
180
+ v.include?(row.fetch(k))
181
+ else
182
+ row.fetch(k) == v
183
+ end
184
+ }
185
+ }
186
+ end
187
+
188
+ private
189
+
190
+ def new_with_query(query)
191
+ self.class.new(database, all_rows, applied_query: query)
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,29 @@
1
+ class QueryCounter
2
+ def initialize
3
+ reset
4
+ end
5
+
6
+ def read_count
7
+ @info.count { |query|
8
+ /\A\([0-9\.]+s\) SELECT/i === query
9
+ }
10
+ end
11
+
12
+ def info(message)
13
+ @info.push(message)
14
+ end
15
+
16
+ def error(message)
17
+ @error.push(message)
18
+ end
19
+
20
+ def warn(message)
21
+ @warn.push(message)
22
+ end
23
+
24
+ def reset
25
+ @info = []
26
+ @error = []
27
+ @warn = []
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_mapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Best
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pg
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.17.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.17.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: sequel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.16'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.16'
97
+ description: ''
98
+ email:
99
+ - bestie@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".ruby-version"
107
+ - Gemfile
108
+ - Gemfile.lock
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - TODO.md
113
+ - lib/sequel_mapper.rb
114
+ - lib/sequel_mapper/association_proxy.rb
115
+ - lib/sequel_mapper/belongs_to_association_proxy.rb
116
+ - lib/sequel_mapper/graph.rb
117
+ - lib/sequel_mapper/queryable_association_proxy.rb
118
+ - lib/sequel_mapper/struct_factory.rb
119
+ - lib/sequel_mapper/version.rb
120
+ - sequel_mapper.gemspec
121
+ - spec/graph_persistence_spec.rb
122
+ - spec/graph_traversal_spec.rb
123
+ - spec/ordered_association_spec.rb
124
+ - spec/proxying_spec.rb
125
+ - spec/querying_spec.rb
126
+ - spec/sequel_mapper/association_proxy_spec.rb
127
+ - spec/sequel_mapper/belongs_to_association_proxy_spec.rb
128
+ - spec/spec_helper.rb
129
+ - spec/support/graph_fixture.rb
130
+ - spec/support/mock_sequel.rb
131
+ - spec/support/query_counter.rb
132
+ homepage: https://github.com/bestie/sequel_mapper
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.2.2
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: A data mapper built on top of the Sequel database toolkit
156
+ test_files:
157
+ - spec/graph_persistence_spec.rb
158
+ - spec/graph_traversal_spec.rb
159
+ - spec/ordered_association_spec.rb
160
+ - spec/proxying_spec.rb
161
+ - spec/querying_spec.rb
162
+ - spec/sequel_mapper/association_proxy_spec.rb
163
+ - spec/sequel_mapper/belongs_to_association_proxy_spec.rb
164
+ - spec/spec_helper.rb
165
+ - spec/support/graph_fixture.rb
166
+ - spec/support/mock_sequel.rb
167
+ - spec/support/query_counter.rb