xquery 0.1.2 → 0.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c7656940fa572468cfb4ebc256618272f2ec5bac
4
- data.tar.gz: 1eefdf1dc536d6e02a7931fd42515ebb91e0bcd1
3
+ metadata.gz: b1e4c4058ba8d6f621da2a420773cd6b6578c899
4
+ data.tar.gz: 617512ed3fa56d31783c79e6c1dd87cf990a64be
5
5
  SHA512:
6
- metadata.gz: b28e7c6dc0334204ba1bda28a7a027a6d1c9b5037bbcc95123b21d3d476c88227f6d8373186641d8bc20b7b96827e92c348a7139fd5d13d6d0a95ea178d34280
7
- data.tar.gz: 7f2f834c00a79fd9eb0c2eaa97da21f5bb59c7b63c305bec07868751b17d120fa43597221ce246f75010966233a009c664188b79cf6e03f67f37cdc6a20bdb62
6
+ metadata.gz: 1fac614b682fe0b4673aafa5c9acd189ad4fa2a90da997244c427cf728fa62a24c781fb49b6bfca8666e9a2061bbb216ea8abc00a9b2593f707ccb0f675c5408
7
+ data.tar.gz: 0fee5220b9fb5111e27a75979af3b7d40028f636ec31176a0bbca5bf8858ba1dc10af3edfe052a68be898a0f6c9ca05778bd1a8d58b712666ca41adf2120bee3
@@ -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 CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xquery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - jelf
@@ -198,7 +198,13 @@ email:
198
198
  executables: []
199
199
  extensions: []
200
200
  extra_rdoc_files: []
201
- files: []
201
+ files:
202
+ - lib/xquery.rb
203
+ - lib/xquery/abstract.rb
204
+ - lib/xquery/errors.rb
205
+ - lib/xquery/generic.rb
206
+ - lib/xquery/query_proxy.rb
207
+ - lib/xquery/version.rb
202
208
  homepage: https://github.com/JelF/xquery
203
209
  licenses:
204
210
  - WTFPL