babik 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +16 -0
- data/README.md +718 -0
- data/Rakefile +18 -0
- data/lib/babik.rb +122 -0
- data/lib/babik/database.rb +16 -0
- data/lib/babik/queryset.rb +154 -0
- data/lib/babik/queryset/components/aggregation.rb +172 -0
- data/lib/babik/queryset/components/limit.rb +22 -0
- data/lib/babik/queryset/components/order.rb +161 -0
- data/lib/babik/queryset/components/projection.rb +118 -0
- data/lib/babik/queryset/components/select_related.rb +78 -0
- data/lib/babik/queryset/components/sql_renderer.rb +99 -0
- data/lib/babik/queryset/components/where.rb +43 -0
- data/lib/babik/queryset/lib/association/foreign_association_chain.rb +97 -0
- data/lib/babik/queryset/lib/association/select_related_association_chain.rb +32 -0
- data/lib/babik/queryset/lib/condition.rb +103 -0
- data/lib/babik/queryset/lib/field.rb +34 -0
- data/lib/babik/queryset/lib/join/association_joiner.rb +39 -0
- data/lib/babik/queryset/lib/join/join.rb +86 -0
- data/lib/babik/queryset/lib/selection/config.rb +19 -0
- data/lib/babik/queryset/lib/selection/foreign_selection.rb +39 -0
- data/lib/babik/queryset/lib/selection/local_selection.rb +40 -0
- data/lib/babik/queryset/lib/selection/operation/base.rb +126 -0
- data/lib/babik/queryset/lib/selection/operation/date.rb +178 -0
- data/lib/babik/queryset/lib/selection/operation/operations.rb +201 -0
- data/lib/babik/queryset/lib/selection/operation/regex.rb +58 -0
- data/lib/babik/queryset/lib/selection/path/foreign_path.rb +50 -0
- data/lib/babik/queryset/lib/selection/path/local_path.rb +44 -0
- data/lib/babik/queryset/lib/selection/path/path.rb +23 -0
- data/lib/babik/queryset/lib/selection/select_related_selection.rb +38 -0
- data/lib/babik/queryset/lib/selection/selection.rb +19 -0
- data/lib/babik/queryset/lib/update/assignment.rb +108 -0
- data/lib/babik/queryset/mixins/aggregatable.rb +17 -0
- data/lib/babik/queryset/mixins/bounded.rb +38 -0
- data/lib/babik/queryset/mixins/clonable.rb +52 -0
- data/lib/babik/queryset/mixins/countable.rb +44 -0
- data/lib/babik/queryset/mixins/deletable.rb +13 -0
- data/lib/babik/queryset/mixins/distinguishable.rb +27 -0
- data/lib/babik/queryset/mixins/filterable.rb +51 -0
- data/lib/babik/queryset/mixins/limitable.rb +88 -0
- data/lib/babik/queryset/mixins/lockable.rb +31 -0
- data/lib/babik/queryset/mixins/none.rb +16 -0
- data/lib/babik/queryset/mixins/projectable.rb +34 -0
- data/lib/babik/queryset/mixins/related_selector.rb +28 -0
- data/lib/babik/queryset/mixins/set_operations.rb +32 -0
- data/lib/babik/queryset/mixins/sortable.rb +49 -0
- data/lib/babik/queryset/mixins/sql_renderizable.rb +17 -0
- data/lib/babik/queryset/mixins/updatable.rb +14 -0
- data/lib/babik/queryset/templates/default/delete/main.sql.erb +14 -0
- data/lib/babik/queryset/templates/default/select/components/aggregation.sql.erb +5 -0
- data/lib/babik/queryset/templates/default/select/components/from.sql.erb +16 -0
- data/lib/babik/queryset/templates/default/select/components/from_set.sql.erb +3 -0
- data/lib/babik/queryset/templates/default/select/components/from_table.sql.erb +2 -0
- data/lib/babik/queryset/templates/default/select/components/limit.sql.erb +10 -0
- data/lib/babik/queryset/templates/default/select/components/order_by.sql.erb +9 -0
- data/lib/babik/queryset/templates/default/select/components/projection.sql.erb +7 -0
- data/lib/babik/queryset/templates/default/select/components/select_related.sql.erb +26 -0
- data/lib/babik/queryset/templates/default/select/components/where.sql.erb +39 -0
- data/lib/babik/queryset/templates/default/select/main.sql.erb +42 -0
- data/lib/babik/queryset/templates/default/update/main.sql.erb +15 -0
- data/lib/babik/queryset/templates/mssql/select/components/limit.sql.erb +8 -0
- data/lib/babik/queryset/templates/mssql/select/components/order_by.sql.erb +21 -0
- data/lib/babik/queryset/templates/mysql2/delete/main.sql.erb +15 -0
- data/lib/babik/queryset/templates/mysql2/update/main.sql.erb +18 -0
- data/lib/babik/queryset/templates/sqlite3/select/components/from_set.sql.erb +5 -0
- data/test/config/db/schema.rb +83 -0
- data/test/config/models/bad_post.rb +5 -0
- data/test/config/models/bad_tag.rb +5 -0
- data/test/config/models/category.rb +4 -0
- data/test/config/models/geozone.rb +6 -0
- data/test/config/models/group.rb +5 -0
- data/test/config/models/group_user.rb +5 -0
- data/test/config/models/post.rb +24 -0
- data/test/config/models/post_tag.rb +5 -0
- data/test/config/models/tag.rb +5 -0
- data/test/config/models/user.rb +6 -0
- data/test/delete/delete_test.rb +60 -0
- data/test/delete/foreign_conditions_delete_test.rb +57 -0
- data/test/delete/local_conditions_delete_test.rb +20 -0
- data/test/enable_coverage.rb +17 -0
- data/test/lib/selection/operation/log/test-queries.log +1 -0
- data/test/lib/selection/operation/test_date.rb +131 -0
- data/test/lib/selection/operation/test_regex.rb +55 -0
- data/test/other/clone_test.rb +129 -0
- data/test/other/escape_test.rb +21 -0
- data/test/other/inverse_of_required_test.rb +33 -0
- data/test/select/aggregate_test.rb +151 -0
- data/test/select/bounds_test.rb +46 -0
- data/test/select/count_test.rb +147 -0
- data/test/select/distinct_test.rb +38 -0
- data/test/select/exclude_test.rb +72 -0
- data/test/select/filter_from_object_test.rb +125 -0
- data/test/select/filter_test.rb +207 -0
- data/test/select/for_update_test.rb +19 -0
- data/test/select/foreign_selection_test.rb +60 -0
- data/test/select/get_test.rb +40 -0
- data/test/select/limit_test.rb +109 -0
- data/test/select/local_selection_test.rb +24 -0
- data/test/select/lookup_test.rb +208 -0
- data/test/select/none_test.rb +40 -0
- data/test/select/order_test.rb +165 -0
- data/test/select/project_test.rb +107 -0
- data/test/select/select_related_test.rb +124 -0
- data/test/select/subquery_test.rb +50 -0
- data/test/set_operations/basic_usage_test.rb +121 -0
- data/test/test_helper.rb +55 -0
- data/test/update/update_test.rb +93 -0
- metadata +278 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Functionality related to the size of the QuerySet
|
6
|
+
module Countable
|
7
|
+
|
8
|
+
# Return the number of elements that match the condition defined by successive calls of filter and exclude.
|
9
|
+
# @return [Integer] Number of elements that match the condition defined in this QuerySet.
|
10
|
+
def count
|
11
|
+
self.all.count
|
12
|
+
end
|
13
|
+
|
14
|
+
# Inform if the QuerySet has no elements that match the condition.
|
15
|
+
# @return [Boolean] True if no records match the filter, false otherwise.
|
16
|
+
def empty?
|
17
|
+
self.count.zero?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Inform if the QuerySet has at least one element that match the condition.
|
21
|
+
# @return [Boolean] True if one or more records match the filter, false otherwise.
|
22
|
+
def exists?
|
23
|
+
self.count.positive?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Return the number of elements that match the condition defined by successive calls of filter and exclude.
|
27
|
+
# Alias of count.
|
28
|
+
# @see Babik::QuerySet::Countable#count
|
29
|
+
# @return [Integer] Number of elements that match the condition defined in this QuerySet.
|
30
|
+
def length
|
31
|
+
self.count
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return the number of elements that match the condition defined by successive calls of filter and exclude.
|
35
|
+
# Alias of count.
|
36
|
+
# @see Babik::QuerySet::Countable#count
|
37
|
+
# @return [Integer] Number of elements that match the condition defined in this QuerySet.
|
38
|
+
def size
|
39
|
+
self.count
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Functionality related to the DELETE operation
|
6
|
+
module Deletable
|
7
|
+
# Delete the selected records
|
8
|
+
def delete
|
9
|
+
result = @model.connection.execute(sql.delete)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Distinguishable functionality for QuerySet
|
6
|
+
module Distinguishable
|
7
|
+
|
8
|
+
# Mark this QuerySet as distinguishable.
|
9
|
+
# Modify this object
|
10
|
+
# (i.e. DISTINCT keyword will be applied to the final SQL query).
|
11
|
+
# @return [QuerySet] Reference to this QuerySet.
|
12
|
+
def distinct!
|
13
|
+
@_distinct = true
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Mark this QuerySet as not distinguishable
|
18
|
+
# (i.e. DISTINCT keyword will NOT be applied to query).
|
19
|
+
# @return [QuerySet] Reference to this QuerySet.
|
20
|
+
def undistinct!
|
21
|
+
@_distinct = false
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Functionality related to the DELETE operation
|
6
|
+
module Filterable
|
7
|
+
# Exclude objects according to some criteria.
|
8
|
+
# @return [QuerySet] Reference to self.
|
9
|
+
def exclude!(filter)
|
10
|
+
_filter(filter, 'exclusion')
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
# Select objects according to some criteria.
|
15
|
+
# @param filter [Array, Hash] if array, it is considered an disjunction (OR clause),
|
16
|
+
# if a hash, it is considered a conjunction (AND clause).
|
17
|
+
# @return [QuerySet] Reference to self.
|
18
|
+
def filter!(filter)
|
19
|
+
_filter(filter, 'inclusion')
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get an single element
|
24
|
+
# @param filter [Array, Hash] if array, it is considered an disjunction (OR clause),
|
25
|
+
# if a hash, it is considered a conjunction (AND clause).
|
26
|
+
# @raise [RuntimeError] Exception:
|
27
|
+
# 'Multiple objects returned' if more than one object matches the condition.
|
28
|
+
# 'Does not exist' if no object match the conditions.
|
29
|
+
# @return [ActiveRecord::Base] object that matches the filter.
|
30
|
+
def get(filter)
|
31
|
+
result_ = self.filter(filter).all
|
32
|
+
result_count = result_.count
|
33
|
+
raise 'Does not exist' if result_count.zero?
|
34
|
+
raise 'Multiple objects returned' if result_count > 1
|
35
|
+
result_.first
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Select the objects according to some criteria.
|
41
|
+
# @param filter [Array, Hash] if array, it is considered an disjunction (OR clause),
|
42
|
+
# if a hash, it is considered a conjunction (AND clause).
|
43
|
+
# @param filter_type [String] Filter type. Must be 'inclusion' or 'exclusion'.
|
44
|
+
# @raise [NoMethodError] if filter_type is not 'inclusion' nor 'exclusion'.
|
45
|
+
def _filter(filter, filter_type)
|
46
|
+
@_where.send("add_#{filter_type}_filter", filter)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Limit functionality of QuerySet
|
6
|
+
module Limitable
|
7
|
+
|
8
|
+
# Configure a limit this QuerySet
|
9
|
+
# @param param [Range, Integer]
|
10
|
+
# If it is a range, first_element..last_element will be selected.
|
11
|
+
# If it is an integer, the element in that position will be returned. No negative number is allowed.
|
12
|
+
# @raise RuntimeError 'Invalid limit passed to query: <VALUE>' If param is not a Range or Integer.
|
13
|
+
# @return [QuerySet, ActiveRecord::Base] QuerySet if a slice was passe as parameter,
|
14
|
+
# otherwise an ActiveRecord model.
|
15
|
+
def [](param)
|
16
|
+
raise "Invalid limit passed to query: #{param}" unless [Range, Integer].include?(param.class)
|
17
|
+
self.clone.send("limit_#{param.class.to_s.downcase}!", param)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Inform if at least one record is matched by this QuerySet
|
21
|
+
# @return [Boolean] True if at least one record matches the conditions of the QuerySet, false otherwise.
|
22
|
+
def exists?
|
23
|
+
element = self.fetch(0, false)
|
24
|
+
return true if element
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return an element at an index, otherwise:
|
29
|
+
# - Return a default value if it has been passed as second argument.
|
30
|
+
# - Raise an IndexError exception
|
31
|
+
# @param index [Integer] Position of the element want to return. No negative number is allowed.
|
32
|
+
# @param default_value [Object] Anything that will be returned if no record is found at the index position.
|
33
|
+
# By default it takes a nil value (in that case, it will raise the IndexError exception).
|
34
|
+
# @raise [IndexError] When there is no default value
|
35
|
+
def fetch(index, default_value = nil)
|
36
|
+
element = self.[](index)
|
37
|
+
return element if element
|
38
|
+
return default_value unless default_value.nil?
|
39
|
+
raise IndexError, "Index #{index} outside of QuerySet bounds"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Configure a limit this QuerySet
|
43
|
+
# @param size [Integer] Number of elements to be selected.
|
44
|
+
# @param offset [Integer] Position where the selection will start. By default is 0. No negative number is allowed.
|
45
|
+
# @return [QuerySet] Reference to this QuerySet.
|
46
|
+
def limit!(size, offset = 0)
|
47
|
+
@_limit = Babik::QuerySet::Limit.new(size, offset)
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# Inform if this QuerySet is limited
|
52
|
+
# @return [Boolean] true if this QuerySet has a limit, false otherwise.
|
53
|
+
def limit?
|
54
|
+
@_limit && true
|
55
|
+
end
|
56
|
+
|
57
|
+
# Destroy the current limit of this QuerySet
|
58
|
+
# @return [QuerySet] Reference to this QuerySet.
|
59
|
+
def unlimit!
|
60
|
+
@_limit = nil
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Get one element at a determined position
|
67
|
+
# @param position [Integer] Position of the element to be returned.
|
68
|
+
# @api private
|
69
|
+
# @return [ActiveRecord::Base, nil] ActiveRecord::Base if exists a record in that position, nil otherwise.
|
70
|
+
def limit_integer!(position)
|
71
|
+
@_limit = Babik::QuerySet::Limit.new(1, position)
|
72
|
+
self.first
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get a QuerySet with a slice of the original QuerySet
|
76
|
+
# @param param [Range] first_element..last_element will be selected.
|
77
|
+
# @api private
|
78
|
+
# @return [QuerySet] QuerySet with a slice of the caller QuerySet.
|
79
|
+
def limit_range!(param)
|
80
|
+
offset = param.min
|
81
|
+
size = param.max.to_i - param.min.to_i
|
82
|
+
@_limit = Babik::QuerySet::Limit.new(size, offset)
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Lock functionality of QuerySet
|
6
|
+
module Lockable
|
7
|
+
|
8
|
+
# Lock the table for writes
|
9
|
+
# This must be inside a transaction
|
10
|
+
def for_update!
|
11
|
+
@_lock_type = 'FOR UPDATE'
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
# Lock the table for writes
|
16
|
+
# This must be inside a transaction
|
17
|
+
# @see #for_update Alias of for_update method
|
18
|
+
def lock!
|
19
|
+
self.for_update!
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check if there is a lock
|
23
|
+
# @return [Boolean] True if there is a lock, false otherwise.
|
24
|
+
def lock?
|
25
|
+
return true if @_lock_type
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# None functionality for QuerySet
|
6
|
+
module NoneQuerySet
|
7
|
+
|
8
|
+
# Return an empty ActiveRecord ResultSet
|
9
|
+
# @return [ResultSet] Empty result set.
|
10
|
+
def none
|
11
|
+
@model.find_by_sql("SELECT * FROM #{@model.table_name} WHERE 1 = 0")
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Project functionality of QuerySet
|
6
|
+
module Projectable
|
7
|
+
|
8
|
+
# Prepares a projection of only some attributes
|
9
|
+
# @param *attributes [Array] Attributes that will be projected.
|
10
|
+
# Each one of these can be a local field, or a foreign entity field.
|
11
|
+
# Babik will take care of joins.
|
12
|
+
# @return [QuerySet] Reference to this QuerySet.
|
13
|
+
def project!(*attributes)
|
14
|
+
@_projection = Babik::QuerySet::Projection.new(@model, attributes)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
# Removes the projection.
|
19
|
+
# @return [QuerySet] Reference to this QuerySet.
|
20
|
+
def unproject!
|
21
|
+
@_projection = nil
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Inform if there is the QuerySet is configured with a projection
|
26
|
+
# @return [Boolean] True if there is a projection configured, false otherwise.
|
27
|
+
def projection?
|
28
|
+
return true if @_projection
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
|
6
|
+
# select_related functionality of QuerySet
|
7
|
+
module RelatedSelector
|
8
|
+
|
9
|
+
# Load the related objects of each model object specified by the association_paths
|
10
|
+
#
|
11
|
+
# e.g.
|
12
|
+
# - User.objects.filter(first_name: 'Julius').select_related(:group)
|
13
|
+
# - User.objects.filter(first_name: 'Cassius').select_related([:group, :zone])
|
14
|
+
# - Post.objects.select_related(:author)
|
15
|
+
#
|
16
|
+
# @param association_paths [Array<Symbol>, Symbol] Array of association paths
|
17
|
+
# of belongs_to and has_one related objects.
|
18
|
+
# A passed symbol will be considered as an array of one symbol.
|
19
|
+
# That is, select_related(:group) is equal to select_related([:group])
|
20
|
+
def select_related!(association_paths)
|
21
|
+
@_select_related = Babik::QuerySet::SelectRelated.new(@model, association_paths)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Set operations over QuerySets
|
6
|
+
module SetOperations
|
7
|
+
|
8
|
+
# Difference (minus) operation
|
9
|
+
# @param other_queryset [QuerySet] Other QuerySet
|
10
|
+
# @return [Babik::QuerySet::Except] Except set operation between this queryset and the other queryset.
|
11
|
+
def difference(other_queryset)
|
12
|
+
Babik::QuerySet::Except.new(self.model, self, other_queryset)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Intersection (except) operation
|
16
|
+
# @param other_queryset [QuerySet] Other QuerySet
|
17
|
+
# @return [Babik::QuerySet::Intersect] Intersection set operation between this queryset and the other queryset.
|
18
|
+
def intersection(other_queryset)
|
19
|
+
Babik::QuerySet::Intersect.new(self.model, self, other_queryset)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Union operation
|
23
|
+
# @param other_queryset [QuerySet] Other QuerySet
|
24
|
+
# @return [Babik::QuerySet::Union] Union set operation between this queryset and the other queryset.
|
25
|
+
def union(other_queryset)
|
26
|
+
Babik::QuerySet::Union.new(self.model, self, other_queryset)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Sort functionality of QuerySet
|
6
|
+
module Sortable
|
7
|
+
|
8
|
+
# Sort QuerySet according to an order
|
9
|
+
# @param order [Array, String, Hash] ordering that will be applied to the QuerySet.
|
10
|
+
# See {Babik::QuerySet::Order#order_by}.
|
11
|
+
# @return [QuerySet] reference to this QuerySet.
|
12
|
+
def order_by!(*order)
|
13
|
+
@_order = Babik::QuerySet::Order.new(@model, *order)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Remove the order on this QuerySet according to an order
|
18
|
+
# @return [QuerySet] reference to this QuerySet.
|
19
|
+
def disorder!
|
20
|
+
@_order = nil
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
# Alias for order_by
|
25
|
+
# @see #order_by
|
26
|
+
# @param order [Array, String, Hash] ordering that will be applied to the QuerySet.
|
27
|
+
# @return [QuerySet] reference to this QuerySet.
|
28
|
+
def order!(*order)
|
29
|
+
order_by!(*order)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Invert the order
|
33
|
+
# e.g.
|
34
|
+
# first_name ASC, last_name ASC, created_at DESC => invert => first_name DESC, last_name DESC, created_at ASC
|
35
|
+
# @return [QuerySet] reference to this QuerySet.
|
36
|
+
def invert_order!
|
37
|
+
@_order.invert!
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# Inform if there is an order for this QuerySet
|
42
|
+
# @return [Boolean] True if this QuerySet is ordered, false otherwise.
|
43
|
+
def ordered?
|
44
|
+
return true if @_order
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Babik
|
4
|
+
module QuerySet
|
5
|
+
# Enumerable functionality for QuerySet
|
6
|
+
module SQLRenderizable
|
7
|
+
|
8
|
+
# Get the SQL renderer for this QuerySet.
|
9
|
+
# @return [QuerySet] SQL Renderer for this QuerySet.
|
10
|
+
def sql
|
11
|
+
renderer = SQLRenderer.new(self)
|
12
|
+
renderer
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|