composite_primary_keys 9.0.4 → 9.0.5
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 +4 -4
- data/History.rdoc +20 -0
- data/Rakefile +37 -34
- data/lib/composite_primary_keys.rb +5 -10
- data/lib/composite_primary_keys/arel/in.rb +6 -6
- data/lib/composite_primary_keys/arel/sqlserver.rb +36 -0
- data/lib/composite_primary_keys/associations/association_scope.rb +51 -29
- data/lib/composite_primary_keys/attribute_methods/read.rb +3 -1
- data/lib/composite_primary_keys/connection_adapters/abstract_mysql_adapter.rb +22 -0
- data/lib/composite_primary_keys/relation.rb +30 -0
- data/lib/composite_primary_keys/relation/query_methods.rb +25 -36
- data/lib/composite_primary_keys/sanitization.rb +31 -47
- data/lib/composite_primary_keys/version.rb +1 -1
- data/tasks/databases/mysql.rake +40 -42
- data/tasks/databases/oracle.rake +29 -15
- data/tasks/databases/postgresql.rake +38 -47
- data/tasks/databases/sqlite.rake +25 -0
- data/tasks/databases/sqlserver.rake +32 -16
- data/test/abstract_unit.rb +12 -11
- data/test/connections/connection_spec.rb +27 -18
- data/test/connections/databases.ci.yml +5 -4
- data/test/connections/databases.example.yml +19 -4
- data/test/connections/databases.yml +25 -4
- data/test/fixtures/article.rb +6 -5
- data/test/fixtures/db_definitions/mysql.sql +16 -7
- data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle.sql +25 -15
- data/test/fixtures/db_definitions/postgresql.sql +11 -2
- data/test/fixtures/db_definitions/sqlite.sql +8 -0
- data/test/fixtures/db_definitions/sqlserver.sql +19 -33
- data/test/fixtures/pk_called_id.rb +5 -0
- data/test/fixtures/pk_called_ids.yml +11 -0
- data/test/test_associations.rb +334 -332
- data/test/test_create.rb +9 -1
- data/test/test_delete.rb +17 -39
- data/test/test_ids.rb +113 -109
- data/test/test_preload.rb +94 -0
- data/test/test_suite.rb +1 -1
- data/test/test_update.rb +12 -7
- metadata +14 -24
- data/lib/composite_primary_keys/associations/singular_association.rb +0 -14
- data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +0 -71
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +0 -50
- data/lib/composite_primary_keys/dirty.rb +0 -19
- data/lib/composite_primary_keys/validations/uniqueness.rb +0 -41
- data/tasks/databases/oracle_enhanced.rake +0 -27
- data/tasks/databases/sqlite3.rake +0 -27
- data/test/connections/native_ibm_db/connection.rb +0 -19
- data/test/connections/native_mysql/connection.rb +0 -17
- data/test/connections/native_oracle/connection.rb +0 -11
- data/test/connections/native_oracle_enhanced/connection.rb +0 -16
- data/test/connections/native_postgresql/connection.rb +0 -13
- data/test/connections/native_sqlite3/connection.rb +0 -9
- data/test/connections/native_sqlserver/connection.rb +0 -11
- data/test/fixtures/db_definitions/sqlserver.drop.sql +0 -92
- data/test/test_delete_all.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a7db1ee79736fa3b98274e9577f650d27c239cd
|
4
|
+
data.tar.gz: 4e121d1420ba01fc56073d176888687ca78d2177
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94556da0f6cfb30ed3285635ebcdbff725d5c7ad9098c3de8b63c3920c93ae1739ab27608f2c32113c8514a688ab1fadd5effddfe05b8c67ccaaed39c7f56b69
|
7
|
+
data.tar.gz: df406dbc3ec9c24df294088f033ec760af5602a3ce09891ad23f5f0200bdfbba4658cf4765fc65c5f4df86ca9f749ee9f7740fb3f7c430751d201e649dd7a7c1
|
data/History.rdoc
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 9.0.5 (2017-01-02)
|
2
|
+
|
3
|
+
* Don't nest PK twice when looking up id, fixes #319 (Kerey Roper)
|
4
|
+
* Simplify database setup for tests (Charlie Savage)
|
5
|
+
* Revamp gem management (Charlie Savage)
|
6
|
+
* Add support for Relation#update_all when using joins (Charlie Savage)
|
7
|
+
* Add erb support to test database.yml files (Charlie Savage)
|
8
|
+
* Sqlserver fixes for ordering (Charlie Savage)
|
9
|
+
* Sqlserver refresh (Charlie Savage)
|
10
|
+
* Oracle refresh (Charlie Savage)
|
11
|
+
* Fix delete_all for MySql (Charlie Savage)
|
12
|
+
* Added test cases for preloading associations with and without conditions (Martin Körner)
|
13
|
+
* Revamp single association handling to correctly setup SQL binds (Charlie Savage)
|
14
|
+
* Remove references to ActiveModel - #352 (Charlie Savage)
|
15
|
+
* Fixes for #232, #359, #367 and #371 (Charlie Savage)
|
16
|
+
|
1
17
|
== 9.0.4 (2016-08-17)
|
2
18
|
* Do not set associations to readonly. See https://github.com/rails/rails/issues/24093 (Charlie Savage)
|
3
19
|
|
@@ -13,6 +29,10 @@
|
|
13
29
|
== 9.0.0.beta1 (2016-04-16)
|
14
30
|
* Rails 5 beta support (Sammy Larbi)
|
15
31
|
|
32
|
+
== 8.1.5 (2017-01-01)
|
33
|
+
|
34
|
+
* Don't nest PK twice when looking up id, fixes #319 (Kerey Roper)
|
35
|
+
|
16
36
|
== 8.1.4 (2016-07-27)
|
17
37
|
|
18
38
|
* Create OR predicates in a nicely balanced tree fixing #320 (Nathan Samson)
|
data/Rakefile
CHANGED
@@ -1,34 +1,37 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'rake/clean'
|
4
|
-
require 'rake/testtask'
|
5
|
-
require 'rubygems/package_task'
|
6
|
-
|
7
|
-
# Set global variable so other tasks can access them
|
8
|
-
::PROJECT_ROOT = File.expand_path(".")
|
9
|
-
::GEM_NAME = 'composite_primary_keys'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
Gem::
|
16
|
-
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
Rake::
|
32
|
-
|
33
|
-
|
34
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
|
7
|
+
# Set global variable so other tasks can access them
|
8
|
+
::PROJECT_ROOT = File.expand_path(".")
|
9
|
+
::GEM_NAME = 'composite_primary_keys'
|
10
|
+
|
11
|
+
require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
|
12
|
+
require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
|
13
|
+
|
14
|
+
# Read the spec file
|
15
|
+
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
16
|
+
|
17
|
+
# Setup Rake tasks for managing the gem
|
18
|
+
Gem::PackageTask.new(spec).define
|
19
|
+
|
20
|
+
# Now load in other task files
|
21
|
+
Dir.glob('tasks/**/*.rake').each do |rake_file|
|
22
|
+
load File.join(File.dirname(__FILE__), rake_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set up test tasks for each supported connection adapter
|
26
|
+
%w(mysql sqlite oracle oracle_enhanced postgresql ibm_db sqlserver).each do |adapter|
|
27
|
+
namespace adapter do
|
28
|
+
desc "Run tests using the #{adapter} adapter"
|
29
|
+
task "test" do
|
30
|
+
ENV["ADAPTER"] = adapter
|
31
|
+
Rake::TestTask.new("subtest_#{adapter}") do |t|
|
32
|
+
t.libs << "test"
|
33
|
+
end
|
34
|
+
Rake::Task["subtest_#{adapter}"].invoke
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2016 Nic Williams and Charlie Savage
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -58,6 +58,7 @@ require 'active_record/locking/optimistic'
|
|
58
58
|
require 'active_record/nested_attributes'
|
59
59
|
|
60
60
|
require 'active_record/connection_adapters/abstract_adapter'
|
61
|
+
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
61
62
|
|
62
63
|
require 'active_record/relation/batches'
|
63
64
|
require 'active_record/relation/where_clause'
|
@@ -66,8 +67,6 @@ require 'active_record/relation/finder_methods'
|
|
66
67
|
require 'active_record/relation/predicate_builder'
|
67
68
|
require 'active_record/relation/query_methods'
|
68
69
|
|
69
|
-
require 'active_record/validations/uniqueness' unless ENV["TESTING_CPK"] == "true"
|
70
|
-
|
71
70
|
# CPK files
|
72
71
|
require 'composite_primary_keys/persistence'
|
73
72
|
require 'composite_primary_keys/base'
|
@@ -89,11 +88,8 @@ require 'composite_primary_keys/associations/join_dependency'
|
|
89
88
|
require 'composite_primary_keys/associations/join_dependency/join_association'
|
90
89
|
require 'composite_primary_keys/associations/preloader/association'
|
91
90
|
require 'composite_primary_keys/associations/preloader/belongs_to'
|
92
|
-
require 'composite_primary_keys/associations/singular_association'
|
93
91
|
require 'composite_primary_keys/associations/collection_association'
|
94
92
|
|
95
|
-
require 'composite_primary_keys/dirty'
|
96
|
-
|
97
93
|
require 'composite_primary_keys/attribute_methods/primary_key'
|
98
94
|
require 'composite_primary_keys/attribute_methods/read'
|
99
95
|
require 'composite_primary_keys/attribute_methods/write'
|
@@ -101,7 +97,7 @@ require 'composite_primary_keys/locking/optimistic'
|
|
101
97
|
require 'composite_primary_keys/nested_attributes'
|
102
98
|
|
103
99
|
require 'composite_primary_keys/connection_adapters/abstract_adapter'
|
104
|
-
require 'composite_primary_keys/connection_adapters/
|
100
|
+
require 'composite_primary_keys/connection_adapters/abstract_mysql_adapter'
|
105
101
|
|
106
102
|
require 'composite_primary_keys/relation/batches'
|
107
103
|
require 'composite_primary_keys/relation/where_clause'
|
@@ -110,9 +106,8 @@ require 'composite_primary_keys/relation/finder_methods'
|
|
110
106
|
require 'composite_primary_keys/relation/predicate_builder'
|
111
107
|
require 'composite_primary_keys/relation/query_methods'
|
112
108
|
|
113
|
-
require 'composite_primary_keys/validations/uniqueness'
|
114
|
-
|
115
109
|
require 'composite_primary_keys/composite_relation'
|
116
110
|
|
117
111
|
require 'composite_primary_keys/arel/in'
|
118
|
-
require 'composite_primary_keys/arel/to_sql'
|
112
|
+
require 'composite_primary_keys/arel/to_sql'
|
113
|
+
require 'composite_primary_keys/arel/sqlserver'
|
@@ -1,6 +1,6 @@
|
|
1
|
-
module CompositePrimaryKeys
|
2
|
-
module Nodes
|
3
|
-
class In < ::Arel::Nodes::Equality
|
4
|
-
end
|
5
|
-
end
|
6
|
-
end
|
1
|
+
module CompositePrimaryKeys
|
2
|
+
module Nodes
|
3
|
+
class In < ::Arel::Nodes::Equality
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class SQLServer
|
4
|
+
def make_Fetch_Possible_And_Deterministic o
|
5
|
+
return if o.limit.nil? && o.offset.nil?
|
6
|
+
t = table_From_Statement o
|
7
|
+
pk = primary_Key_From_Table t
|
8
|
+
return unless pk
|
9
|
+
if o.orders.empty?
|
10
|
+
# Prefer deterministic vs a simple `(SELECT NULL)` expr.
|
11
|
+
# CPK
|
12
|
+
#o.orders = [pk.asc]
|
13
|
+
o.orders = pk.map {|a_pk| a_pk.asc}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def primary_Key_From_Table t
|
18
|
+
return unless t
|
19
|
+
column_name = schema_cache.primary_keys(t.name) || column_cache(t.name).first.second.try(:name)
|
20
|
+
|
21
|
+
# CPK
|
22
|
+
# column_name ? t[column_name] : nil
|
23
|
+
case column_name
|
24
|
+
when Array
|
25
|
+
column_name.map do |name|
|
26
|
+
t[name]
|
27
|
+
end
|
28
|
+
when NilClass
|
29
|
+
[t[column_name]]
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,44 +1,66 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Associations
|
3
3
|
class AssociationScope
|
4
|
-
silence_warnings do
|
5
|
-
def next_chain_scope(scope, table, reflection, association_klass, foreign_table, next_reflection)
|
6
|
-
join_keys = reflection.join_keys(association_klass)
|
7
|
-
key = join_keys.key
|
8
|
-
foreign_key = join_keys.foreign_key
|
9
|
-
# CPK
|
10
|
-
# constraint = table[key].eq(foreign_table[foreign_key])
|
11
|
-
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
12
4
|
|
5
|
+
def self.get_bind_values(owner, chain)
|
6
|
+
binds = []
|
7
|
+
last_reflection = chain.last
|
8
|
+
|
9
|
+
# CPK
|
10
|
+
# binds << last_reflection.join_id_for(owner)
|
11
|
+
values = last_reflection.join_id_for(owner)
|
12
|
+
binds += Array(values)
|
13
|
+
|
14
|
+
if last_reflection.type
|
15
|
+
binds << owner.class.base_class.name
|
16
|
+
end
|
17
|
+
|
18
|
+
chain.each_cons(2).each do |reflection, next_reflection|
|
13
19
|
if reflection.type
|
14
|
-
|
15
|
-
scope = scope.where(table.name => { reflection.type => value })
|
20
|
+
binds << next_reflection.klass.base_class.name
|
16
21
|
end
|
22
|
+
end
|
23
|
+
binds
|
24
|
+
end
|
17
25
|
|
18
|
-
|
26
|
+
def last_chain_scope(scope, table, reflection, owner, association_klass)
|
27
|
+
join_keys = reflection.join_keys(association_klass)
|
28
|
+
key = join_keys.key
|
29
|
+
foreign_key = join_keys.foreign_key
|
30
|
+
|
31
|
+
# CPK
|
32
|
+
#value = transform_value(owner[foreign_key])
|
33
|
+
#scope = scope.where(table.name => { key => value })
|
34
|
+
mappings = Array(key).zip(Array(foreign_key))
|
35
|
+
joins = mappings.reduce(Hash.new) do |hash, mapping|
|
36
|
+
hash[mapping.first] = transform_value(owner[mapping.last])
|
37
|
+
hash
|
19
38
|
end
|
39
|
+
scope = scope.where(table.name => joins)
|
20
40
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# CPK
|
27
|
-
if key.kind_of?(Array) || foreign_key.kind_of?(Array)
|
28
|
-
predicate = cpk_join_predicate(table, key, owner, foreign_key)
|
29
|
-
scope = scope.where(predicate)
|
30
|
-
else
|
31
|
-
value = transform_value(owner[foreign_key])
|
32
|
-
scope = scope.where(table.name => { key => value })
|
33
|
-
end
|
41
|
+
if reflection.type
|
42
|
+
polymorphic_type = transform_value(owner.class.base_class.name)
|
43
|
+
scope = scope.where(table.name => { reflection.type => polymorphic_type })
|
44
|
+
end
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
scope = scope.where(table.name => { reflection.type => polymorphic_type })
|
38
|
-
end
|
46
|
+
scope
|
47
|
+
end
|
39
48
|
|
40
|
-
|
49
|
+
def next_chain_scope(scope, table, reflection, association_klass, foreign_table, next_reflection)
|
50
|
+
join_keys = reflection.join_keys(association_klass)
|
51
|
+
key = join_keys.key
|
52
|
+
foreign_key = join_keys.foreign_key
|
53
|
+
|
54
|
+
# CPK
|
55
|
+
# constraint = table[key].eq(foreign_table[foreign_key])
|
56
|
+
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
57
|
+
|
58
|
+
if reflection.type
|
59
|
+
value = transform_value(next_reflection.klass.base_class.name)
|
60
|
+
scope = scope.where(table.name => { reflection.type => value })
|
41
61
|
end
|
62
|
+
|
63
|
+
scope = scope.joins(join(foreign_table, constraint))
|
42
64
|
end
|
43
65
|
end
|
44
66
|
end
|
@@ -8,7 +8,9 @@ module ActiveRecord
|
|
8
8
|
_read_attribute(attr_name, &block)
|
9
9
|
else
|
10
10
|
name = attr_name.to_s
|
11
|
-
|
11
|
+
# CPK
|
12
|
+
#name = self.class.primary_key if name == 'id'.freeze
|
13
|
+
name = self.class.primary_key if name == 'id'.freeze && !composite?
|
12
14
|
_read_attribute(name, &block)
|
13
15
|
end
|
14
16
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class AbstractMysqlAdapter
|
4
|
+
def subquery_for(key, select)
|
5
|
+
subsubselect = select.clone
|
6
|
+
subsubselect.projections = [key]
|
7
|
+
|
8
|
+
# Materialize subquery by adding distinct
|
9
|
+
# to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
|
10
|
+
subsubselect.distinct unless select.limit || select.offset || select.orders.any?
|
11
|
+
|
12
|
+
subselect = Arel::SelectManager.new(select.engine)
|
13
|
+
|
14
|
+
# CPK
|
15
|
+
#subselect.project Arel.sql(key.name)
|
16
|
+
subselect.project Arel.sql(Array(key).map(&:name).join(', '))
|
17
|
+
|
18
|
+
subselect.from subsubselect.as('__active_record_temp')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -47,6 +47,36 @@ module ActiveRecord
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def update_all(updates)
|
51
|
+
raise ArgumentError, "Empty list of attributes to change" if updates.blank?
|
52
|
+
|
53
|
+
stmt = Arel::UpdateManager.new
|
54
|
+
|
55
|
+
stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
|
56
|
+
stmt.table(table)
|
57
|
+
|
58
|
+
if joins_values.any?
|
59
|
+
# CPK
|
60
|
+
#@klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
|
61
|
+
if primary_key.kind_of?(Array)
|
62
|
+
attributes = primary_key.map do |key|
|
63
|
+
arel_attribute(key)
|
64
|
+
end
|
65
|
+
@klass.connection.join_to_update(stmt, arel, attributes.to_composite_keys)
|
66
|
+
else
|
67
|
+
@klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
|
68
|
+
end
|
69
|
+
else
|
70
|
+
stmt.key = arel_attribute(primary_key)
|
71
|
+
stmt.take(arel.limit)
|
72
|
+
stmt.order(*arel.orders)
|
73
|
+
stmt.wheres = arel.constraints
|
74
|
+
end
|
75
|
+
|
76
|
+
@klass.connection.update stmt, 'SQL', bound_attributes
|
77
|
+
end
|
78
|
+
|
79
|
+
|
50
80
|
def delete_all(conditions = nil)
|
51
81
|
invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select { |method|
|
52
82
|
if MULTI_VALUE_METHODS.include?(method)
|
@@ -1,41 +1,30 @@
|
|
1
|
-
module CompositePrimaryKeys
|
1
|
+
module CompositePrimaryKeys
|
2
|
+
module ActiveRecord
|
3
|
+
module QueryMethods
|
4
|
+
def reverse_sql_order(order_query)
|
5
|
+
# CPK
|
6
|
+
# order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
8
|
+
# break apart CPKs
|
9
|
+
order_query = primary_key.map do |key|
|
10
|
+
"#{quoted_table_name}.#{connection.quote_column_name(key)} ASC"
|
11
|
+
end if order_query.empty?
|
6
12
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
else
|
22
|
-
o
|
23
|
-
end
|
24
|
-
end.flatten
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
def order(*args)
|
29
|
-
args.map! do |arg|
|
30
|
-
if arg.is_a?(Arel::Nodes::Ordering) && arg.expr.name.is_a?(Array)
|
31
|
-
arg = arg.expr.name.map do |key|
|
32
|
-
cloned_node = arg.clone
|
33
|
-
cloned_node.expr.name = key
|
34
|
-
cloned_node
|
35
|
-
end
|
13
|
+
order_query.map do |o|
|
14
|
+
case o
|
15
|
+
when Arel::Nodes::Ordering
|
16
|
+
o.reverse
|
17
|
+
when String, Symbol
|
18
|
+
o.to_s.split(',').collect do |s|
|
19
|
+
s.strip!
|
20
|
+
s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
|
21
|
+
end
|
22
|
+
else
|
23
|
+
o
|
24
|
+
end
|
25
|
+
end.flatten
|
36
26
|
end
|
37
|
-
|
38
|
-
end if composite?
|
39
|
-
super(*args)
|
27
|
+
end
|
40
28
|
end
|
41
29
|
end
|
30
|
+
|