xquery 0.1.3-java

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 33e6fdb5a289ea9dd885be6ecb0abe3ce0db6829
4
+ data.tar.gz: d7759edc915b5c87dfe1ddbe92699e4fa4ba7f0a
5
+ SHA512:
6
+ metadata.gz: b6e8ad5cba36841f9eab41f4c1c4f5d21481296958ed44a6f69adbe54f010e74ac22f9d6fef5d9f64ac3f8b25f876035f305cf379526fdac252cbf37b5906b17
7
+ data.tar.gz: ad988f2174be9ad81271da984ab14591ba6ad542421324cfb1cab68f556dfcba3232130ce0e86c6df248b7a03fc9f5090bcc3e54f35013d960e34020c0e3f30a
@@ -0,0 +1,10 @@
1
+ require 'active_support'
2
+
3
+ # XQuery is designed to replace boring method call chains and allow to easier
4
+ # convert it in a builder classes
5
+ # see [README.md] for more information
6
+ module XQuery
7
+ end
8
+
9
+ require 'xquery/version'
10
+ require 'xquery/generic'
@@ -0,0 +1,104 @@
1
+ require 'active_support/core_ext/class/attribute.rb'
2
+
3
+ require 'xquery/query_proxy'
4
+ require 'xquery/errors'
5
+
6
+ module XQuery
7
+ # abstract superclass, should be inherited, not used
8
+ class Abstract
9
+ class_attribute :query_superclass
10
+
11
+ # yields instance inside block. I suggest to name it `q`
12
+ # @param args [Array(Object)] array of arguments would be passed to
13
+ # @param block [#to_proc] block to witch instance would be yielded
14
+ def self.with(*args, &block)
15
+ instance = new(*args)
16
+ block.call(instance)
17
+ instance.query
18
+ end
19
+
20
+ class << self
21
+ alias_method :execute, :with
22
+ end
23
+
24
+ # Defines `method`, `__method` and `q.method`.
25
+ # Both of wich changes query to query.method
26
+ # @param name [#to_sym] name of method on query
27
+ # @param as [#to_sym] name of method defined
28
+ def self.wrap_method(name, as: name)
29
+ define_method(as) { |*args, &block| _update_query(name, *args, &block) }
30
+ alias_on_q(as, true)
31
+ end
32
+
33
+ # same as wrap_method, but hanldes multiply methods
34
+ # @param methods [Array(#to_sym)] names of methods defined
35
+ def self.wrap_methods(*methods)
36
+ methods.each(&method(:wrap_method))
37
+ end
38
+
39
+ # Aliases method to __method and q.method
40
+ # @param name [#to_sym] name of method
41
+ # @param return_self [Boolean] should defined method return self or result
42
+ def self.alias_on_q(name, return_self = false)
43
+ alias_method("__#{name}", name)
44
+ private("__#{name}")
45
+
46
+ query_proxy.send(:define_method, name) do |*args, &block|
47
+ result = instance.send("__#{name}", *args, &block)
48
+ return_self ? self : result
49
+ end
50
+ end
51
+
52
+ # @return [Class] query_proxy (`q`) class
53
+ def self.query_proxy
54
+ @query_proxy ||= Class.new(QueryProxy)
55
+ end
56
+
57
+ # inherited classes should also have their query_proxies inherited
58
+ def self.inherited(child)
59
+ child.instance_variable_set(:@query_proxy, Class.new(query_proxy))
60
+ end
61
+
62
+ # contains current state of wrapped query
63
+ attr_reader :query
64
+
65
+ # @param query [Object] generic query
66
+ def initialize(query)
67
+ self.query = query
68
+ @query_proxy = self.class.query_proxy.new(self)
69
+ end
70
+
71
+ # yields query inside block
72
+ # @param block [#to_proc]
73
+ # @return [XQuery::Abstract] self
74
+ def apply(&block)
75
+ self.query = block.call(query)
76
+ self
77
+ end
78
+
79
+ private
80
+
81
+ # @private_api
82
+ # updates query by calling method on it and storing the result
83
+ # @return [XQuery::Abstract] self
84
+ def _update_query(method, *args, &block)
85
+ apply { |x| x.public_send(method, *args, &block) }
86
+ end
87
+
88
+ # added constraints check
89
+ # @raise XQuery::QuerySuperclassChanged
90
+ def query=(x)
91
+ unless x.is_a?(query_superclass)
92
+ fail QuerySuperclassChanged.new(x, query_superclass)
93
+ end
94
+
95
+ @query = x
96
+ end
97
+
98
+ # @return [XQuery::QueryProxy] object could be used
99
+ # to access method wrappers unchanged
100
+ def q
101
+ @query_proxy
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,18 @@
1
+ module XQuery
2
+ # raised when superclass of query changed
3
+ class QuerySuperclassChanged < StandardError
4
+ # query on which constraint failed
5
+ attr_reader :result
6
+
7
+ # expected superclass of query
8
+ attr_reader :expectation
9
+
10
+ # @param result [Object] query on which constraint failed
11
+ # @param expectation [Class] expected superclass
12
+ def initialize(result, expectation)
13
+ @result = result
14
+ @expectation = expectation
15
+ super("Expected #{result.inspect} to be an instance of #{expectation}")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ require 'xquery/abstract'
2
+
3
+ module XQuery
4
+ # delegates all operations to model
5
+ class Generic < Abstract
6
+ # never used but defined in case of need
7
+ self.query_superclass = Object
8
+
9
+ # all missing methods would be delegated to query
10
+ # and processed as wrappers process them
11
+ def method_missing(name, *args, &block)
12
+ super unless respond_to_missing?(name)
13
+ _update_query(name, *args, &block)
14
+ end
15
+
16
+ # respond to all public model methods
17
+ def respond_to_missing?(name, *)
18
+ query.respond_to?(name, true)
19
+ end
20
+
21
+ private
22
+
23
+ # q object refers to self, not proxy
24
+ def q
25
+ self
26
+ end
27
+ end
28
+ end
29
+
30
+ # Allows you to do all query magic on a generic object
31
+ # @param model [Object] any object
32
+ # @param block [#to_proc] block where instance will be yielded
33
+ def XQuery(model, &block)
34
+ XQuery::Generic.with(model, &block)
35
+ end
@@ -0,0 +1,15 @@
1
+ module XQuery
2
+ # This proxy can be used to access raw wrappers inside classes,
3
+ # inherited from XQuery::Abstract
4
+ class QueryProxy
5
+ # @param instance [Xquery::Abstract] instance to delegate methods
6
+ def initialize(instance)
7
+ self.instance = instance
8
+ end
9
+
10
+ private
11
+
12
+ # instance of Xquery::Abstract
13
+ attr_accessor :instance
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module XQuery
2
+ # defines XQuery version
3
+ VERSION = '0.1.3'
4
+ end
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xquery
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: java
6
+ authors:
7
+ - jelf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '4.0'
19
+ name: activesupport
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.10'
33
+ name: bundler
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.3'
47
+ name: rspec
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.10'
61
+ name: pry
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.4'
75
+ name: rake
76
+ prerelease: false
77
+ type: :development
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.4'
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.35'
89
+ name: rubocop
90
+ prerelease: false
91
+ type: :development
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.35'
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.8'
103
+ name: yard
104
+ prerelease: false
105
+ type: :development
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.8'
111
+ - !ruby/object:Gem::Dependency
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.11'
117
+ name: simplecov
118
+ prerelease: false
119
+ type: :development
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.11'
125
+ description: |
126
+ # XQuery
127
+ XQuery is designed to replace boring method call chains and allow to easier
128
+ convert it in a builder classes
129
+ [![Build Status](https://travis-ci.org/JelF/xquery.svg?branch=master)](https://travis-ci.org/JelF/xquery)
130
+ ## Usage of `XQuery` function
131
+ `Xquery` is a shortcat to `Xquery::Generic.with`
132
+
133
+ ```
134
+ r = XQuery(''.html_safe) do |q|
135
+ # similar to tap
136
+ q << 'bla bla bla'
137
+ q << 'bla bla bla'
138
+ # using truncate
139
+ q.truncate(15)
140
+ # real content (q.send(:query)) mutated
141
+ q << '!'
142
+ end
143
+ r # => "bla bla blab...!"
144
+ ```
145
+ ## Usage of `XQuery::Abstract`
146
+ I designed this gem to help me with `ActiveRecord` Queries, so i inherited
147
+ `XQuery::Abstract` and used it's powers. It provides the following features
148
+ ### `wrap_method` and `wrap_methods`
149
+ when you call each of this methods they became automatically wrapped
150
+ (`XQuery::Abstract` basically wraps all methods query `#respond_to?`)
151
+ It means, that there are instance methods with same name defined and will
152
+ change a `#query` to their call result.
153
+ ```
154
+ self.query = query.foo(x)
155
+ # is basically the same as
156
+ foo(x)
157
+ # when `wrap_method :foo` called
158
+ ```
159
+
160
+ You can also specify new name using `wrap_method :foo, as: :bar` syntax
161
+ ### `q` object
162
+ `q` is a proxy object which holds all of wrapped methods,
163
+ but not methods you defined inside your class.
164
+ E.g. i have defined `wrap_method(:foo)`, but also delegated `#foo` to some
165
+ another object. If i call `q.foo`, i will get wrapped method.
166
+ Note, that if you redefine `#__foo` method, q.foo will call it instead of
167
+ normal work.
168
+ You can add additional methods to `q` using something like `alias_on_q :foo`.
169
+ I used it with `kaminary` and it was useful
170
+ ```
171
+ def page=(x)
172
+ apply { |query| query.page(x) }
173
+ end
174
+ alias_on_q :page=
175
+
176
+ def page
177
+ query.current_page
178
+ end
179
+ alias_on_q :page
180
+ ```
181
+
182
+ ### `query_superclass`
183
+ You should specify `query_superclass` class_attribute to inherit
184
+ `XQuery::Abstract`. Whenever `query.is_a?(query_superclass)` evaluate to false,
185
+ you will get `XQuery::QuerySuperclassChanged` exception.
186
+ It can save you much time when your class misconfigured.
187
+ E.g. you are using `select!` and it returns `nil`, because why not?
188
+
189
+ ### `#apply` method
190
+ `#apply` does exact what it source tells
191
+ ```
192
+ # yields query inside block
193
+ # @param block [#to_proc]
194
+ # @return [XQuery::Abstract] self
195
+ def apply(&block)
196
+ self.query = block.call(query)
197
+ self
198
+ end
199
+ ```
200
+ It is usefull to merge different queries.
201
+
202
+ ### `with` class method
203
+ You can get XQuery functionality even you have not defined a specific class
204
+ (You are still have to inherit XQuery::Abstract to use it)
205
+ You can see it in this document when i described `XQuery` function.
206
+ Note, that it yields a class instance, not `q` object.
207
+ It accepts any arguments, they will be passed to a constructor (except block)
208
+ If you want only to call one function on an instance (e.g. `#apply`),
209
+ you should prefer `execute` alias
210
+ email:
211
+ - begdory4+xquery@gmail.com
212
+ executables: []
213
+ extensions: []
214
+ extra_rdoc_files: []
215
+ files:
216
+ - lib/xquery.rb
217
+ - lib/xquery/abstract.rb
218
+ - lib/xquery/errors.rb
219
+ - lib/xquery/generic.rb
220
+ - lib/xquery/query_proxy.rb
221
+ - lib/xquery/version.rb
222
+ homepage: https://github.com/JelF/xquery
223
+ licenses:
224
+ - WTFPL
225
+ metadata: {}
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
233
+ - !ruby/object:Gem::Version
234
+ version: '0'
235
+ required_rubygems_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ requirements: []
241
+ rubyforge_project:
242
+ rubygems_version: 2.4.8
243
+ signing_key:
244
+ specification_version: 4
245
+ summary: XQuery is designed to replace boring method call chains and allow to easier convert it in a builder classes see README.md for more information
246
+ test_files: []
247
+ has_rdoc: