arspy 0.0.2 → 0.0.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.
- data/lib/arspy/class_extensions.rb +2 -2
- data/lib/arspy/delegators/active_record_extensions.rb +2 -2
- data/lib/arspy/delegators/array_extensions.rb +2 -2
- data/lib/arspy/delegators/association_collection_extensions.rb +2 -2
- data/lib/arspy/operators.rb +88 -17
- data/spec/database.rb +54 -37
- metadata +3 -3
@@ -2,8 +2,8 @@ module Arspy
|
|
2
2
|
module ClassExtensions
|
3
3
|
module ActiveRecord
|
4
4
|
module Base
|
5
|
-
def la; Arspy::Operators.
|
6
|
-
def lf; Arspy::Operators.
|
5
|
+
def la; Arspy::Operators.list_associations(self); end
|
6
|
+
def lf; Arspy::Operators.list_fields(self); end
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -2,8 +2,8 @@ module Arspy
|
|
2
2
|
module Delegators
|
3
3
|
module ActiveRecordExtensions
|
4
4
|
def pr(*args); Arspy::Operators.print_object(self, *args); end
|
5
|
-
def la; Arspy::Operators.
|
6
|
-
def lf; Arspy::Operators.
|
5
|
+
def la; Arspy::Operators.list_associations(self.class); end
|
6
|
+
def lf; Arspy::Operators.list_fields(self.class); end
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -14,10 +14,10 @@ module Arspy
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def la
|
17
|
-
Arspy::Operators.
|
17
|
+
Arspy::Operators.list_associations(self.first.class) unless (self.emtpy? || !(self.first.is_a?(ActiveRecord::Base)))
|
18
18
|
end
|
19
19
|
def lf
|
20
|
-
Arspy::Operators.
|
20
|
+
Arspy::Operators.list_fields(self.first.class) unless (self.empty? || !(self.first.is_a?(ActiveRecord::Base)))
|
21
21
|
end
|
22
22
|
def pr(*args)
|
23
23
|
Arspy::Operators.print_array(self, *args)
|
@@ -15,11 +15,11 @@ module Arspy
|
|
15
15
|
end
|
16
16
|
def la
|
17
17
|
load_target unless loaded?
|
18
|
-
Arspy::Operators.
|
18
|
+
Arspy::Operators.list_associations(@target.first.class) unless (@target.emtpy? || !(@target.first.is_a?(ActiveRecord::Base)))
|
19
19
|
end
|
20
20
|
def lf
|
21
21
|
load_target unless loaded?
|
22
|
-
Arspy::Operators.
|
22
|
+
Arspy::Operators.list_fields(@target.first.class) unless (@target.empty? || !(@target.first.is_a?(ActiveRecord::Base)))
|
23
23
|
end
|
24
24
|
def wi(*args)
|
25
25
|
load_target unless loaded?
|
data/lib/arspy/operators.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Arspy
|
2
2
|
module Operators
|
3
|
-
def self.
|
3
|
+
def self.list_associations(active_record_klass)
|
4
4
|
counts = {}
|
5
5
|
rows = active_record_klass.reflect_on_all_associations.map do |a|
|
6
6
|
counts[a.macro] ||= 0
|
@@ -12,7 +12,7 @@ module Arspy
|
|
12
12
|
"Total: #{counts.inject(0){|sum, c| sum+c.last}} (" + counts.map{|c| "#{c.last} #{c.first}" }.join(', ') + ")"
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.
|
15
|
+
def self.list_fields(active_record_klass)
|
16
16
|
rows = active_record_klass.columns.map do |c|
|
17
17
|
self.format_column_field(c)
|
18
18
|
end
|
@@ -70,20 +70,96 @@ module Arspy
|
|
70
70
|
return array if (args.empty? || array.nil? || array.empty?)
|
71
71
|
array.select{|o| o && !self.test_object(o, args)}
|
72
72
|
end
|
73
|
-
def self.
|
74
|
-
|
73
|
+
def self.enable_abbreviations; @@abbreviations_enabled = true; end
|
74
|
+
def self.disable_abbreviations; @@abbreviations_enabled = false; end
|
75
|
+
@@abbreviations_enabled = true
|
76
|
+
def self.interpret(array, method_name, *args)
|
77
|
+
return nil unless (array && method_name)
|
75
78
|
return nil unless (array.is_a?(Array) && !array.empty? && array.first.is_a?(ActiveRecord::Base))
|
76
79
|
|
77
|
-
if array.first.class.reflect_on_all_associations.detect{|a| a.name ==
|
78
|
-
array
|
79
|
-
elsif (array.first.attribute_names.include?(
|
80
|
-
return array
|
81
|
-
raise 'Hash not allowed as attribute conditionals' if args.any?{|a| a.is_a?(Hash)}
|
82
|
-
array.select{|o| o && self.test_attribute(o, symbol, args)}
|
83
|
-
else
|
84
|
-
nil
|
80
|
+
if array.first.class.reflect_on_all_associations.detect{|a| a.name == method_name}
|
81
|
+
return interpret_association(array, method_name, *args)
|
82
|
+
elsif (array.first.attribute_names.include?(method_name.to_s) || array.first.respond_to?(method_name))
|
83
|
+
return interpret_attribute_or_method(array, method_name, *args)
|
85
84
|
end
|
85
|
+
return @@abbreviations_enabled ? interpret_abbreviation(array, method_name, *args) : nil
|
86
86
|
end
|
87
|
+
private
|
88
|
+
def self.interpret_abbreviation(array, symbol, *args)
|
89
|
+
if (descriptor = resolve_abbreviation_for_attributes_and_associations(array.first, symbol))
|
90
|
+
if descriptor[:type] == :association
|
91
|
+
return interpret_association(array, descriptor[:method_name], *args)
|
92
|
+
else
|
93
|
+
return interpret_attribute_or_method(array, descriptor[:method_name], *args)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
def self.resolve_abbreviation_for_attributes_and_associations(object, method_name)
|
99
|
+
klass = object.class
|
100
|
+
setup_abbreviations(object) unless object.instance_variable_defined?('@arspy_abbreviations')
|
101
|
+
if (ambiguity = klass.instance_variable_get('@arspy_ambiguous_abbreviations')[method_name])
|
102
|
+
raise "Ambiguous abbreviation '#{ambiguity[:abbr]}' could be #{quote_and_join(ambiguity[:methods])}"
|
103
|
+
end
|
104
|
+
klass.instance_variable_get('@arspy_abbreviations')[method_name]
|
105
|
+
end
|
106
|
+
def self.setup_abbreviations(object)
|
107
|
+
associations = object.class.reflect_on_all_associations.map(&:name).map(&:to_sym)
|
108
|
+
attributes = object.attribute_names.map(&:to_sym)
|
109
|
+
assoc_descriptors = associations.map{|method_name| {:method_name=>method_name, :type=>:association, :abbr=>abbreviate_method_name(method_name)}}
|
110
|
+
attrib_descriptors = attributes.map{|method_name| {:method_name=>method_name, :type=>:attribute, :abbr=>abbreviate_method_name(method_name)}}
|
111
|
+
all_descriptors = assoc_descriptors + attrib_descriptors
|
112
|
+
object.class.instance_variable_set('@arspy_ambiguous_abbreviations', remove_ambiguities(all_descriptors))
|
113
|
+
object.class.instance_variable_set('@arspy_abbreviations', Hash[*all_descriptors.map{|d| [d[:abbr], d] }.flatten])
|
114
|
+
end
|
115
|
+
def self.remove_ambiguities(descriptors)
|
116
|
+
list={}
|
117
|
+
ambiguities = {}
|
118
|
+
descriptors.each do |d|
|
119
|
+
if list.include?(d[:abbr])
|
120
|
+
if ambiguities[d[:abbr]]
|
121
|
+
ambiguities[d[:abbr]][:methods] << d[:method_name]
|
122
|
+
else
|
123
|
+
ambiguities[d[:abbr]] = {:abbr=>d[:abbr], :methods=>[d[:method_name]]}
|
124
|
+
ambiguities[d[:abbr]][:methods] << list[d[:abbr]][:method_name]
|
125
|
+
end
|
126
|
+
else
|
127
|
+
list[d[:abbr]] = d
|
128
|
+
end
|
129
|
+
end
|
130
|
+
descriptors.reject!{|d| ambiguities.map{|h| h.first}.include?(d[:abbr])}
|
131
|
+
ambiguities
|
132
|
+
end
|
133
|
+
def self.abbreviate_method_name(method_name)
|
134
|
+
splits = method_name.to_s.split('_')
|
135
|
+
abbr=[]
|
136
|
+
if splits.first == ''
|
137
|
+
abbr << '_'
|
138
|
+
end
|
139
|
+
splits.reject!{|s| s == ''}
|
140
|
+
abbr += splits.map do |s|
|
141
|
+
chars = s.split(//)
|
142
|
+
first = chars.shift
|
143
|
+
[first, chars.map{|ch| ch =~ /[0-9]/ ? ch : nil}].compact.flatten.join('')
|
144
|
+
end
|
145
|
+
|
146
|
+
abbr << '_' if (method_name.to_s =~ /_$/)
|
147
|
+
abbr.join('').to_sym
|
148
|
+
end
|
149
|
+
def self.quote_and_join(array)
|
150
|
+
return "'#{array.first}'" if array.size == 1
|
151
|
+
last = array.pop
|
152
|
+
"'#{array.join("', '")}' or '#{last}'"
|
153
|
+
end
|
154
|
+
def self.interpret_association(array, method_name, *args)
|
155
|
+
array.map(&method_name).flatten
|
156
|
+
end
|
157
|
+
def self.interpret_attribute_or_method(array, method_name, *args)
|
158
|
+
return array.map(&method_name) if args.empty?
|
159
|
+
raise 'Hash not allowed as attribute conditionals' if args.any?{|a| a.is_a?(Hash)}
|
160
|
+
array.select{|o| o && self.test_attribute(o, method_name, args)}
|
161
|
+
end
|
162
|
+
public
|
87
163
|
|
88
164
|
def self.test_attribute(obj, attr_sym, args)
|
89
165
|
return false if (obj.nil? || attr_sym.nil? || args.empty?)
|
@@ -101,11 +177,6 @@ module Arspy
|
|
101
177
|
end
|
102
178
|
end
|
103
179
|
|
104
|
-
def self.prepare_arguments(symbol, *args)
|
105
|
-
return nil if args.empty?
|
106
|
-
Hash[*args.map{|a| a.is_a?(Hash) ? a.map{|k,v| [k, v]} : [symbol, a]}.flatten]
|
107
|
-
end
|
108
|
-
|
109
180
|
@@column_padding = 2
|
110
181
|
def self.print_matrix(matrix_array)
|
111
182
|
return nil if matrix_array.empty?
|
data/spec/database.rb
CHANGED
@@ -1,63 +1,80 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.
|
3
|
+
gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.3.2'
|
4
4
|
require 'active_record'
|
5
5
|
|
6
6
|
ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'})
|
7
7
|
ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/active_record.log")
|
8
8
|
cx = ActiveRecord::Base.connection
|
9
9
|
|
10
|
-
cx.create_table(:
|
11
|
-
|
10
|
+
cx.create_table(:people, :force=>true) do |t|
|
11
|
+
t.string :first_name
|
12
|
+
t.string :last_name
|
13
|
+
t.integer :age
|
14
|
+
t.boolean :active
|
12
15
|
end
|
13
|
-
cx.create_table(:one_manies, :force=>true) do |t|
|
14
16
|
|
17
|
+
class Person < ActiveRecord::Base
|
18
|
+
has_many :friendships
|
19
|
+
has_many :friends, :through=>:friendships
|
20
|
+
has_many :blogs
|
21
|
+
has_many :comments
|
22
|
+
|
23
|
+
def full_name; "#{first_name} #{last_name}"; end
|
15
24
|
end
|
16
|
-
cx.create_table(:many_manies, :force=>true) do |t|
|
17
25
|
|
26
|
+
cx.create_table(:friendships, :force=>true) do |t|
|
27
|
+
t.references :person
|
28
|
+
t.references :friend
|
29
|
+
t.integer :years_known
|
18
30
|
end
|
19
|
-
cx.create_table(:many_manies_things, :force=>true) do |t|
|
20
31
|
|
32
|
+
class Friendship < ActiveRecord::Base
|
33
|
+
belongs_to :person
|
34
|
+
belongs_to :friend, :class=>'Person'
|
21
35
|
end
|
22
|
-
cx.create_table(:manies_one, :force=>true) do |t|
|
23
36
|
|
37
|
+
cx.create_table(:blogs, :force=>true) do |t|
|
38
|
+
t.references :person
|
39
|
+
t.string :title
|
40
|
+
t.datetime :published_at
|
41
|
+
t.references :asset, :polymorphic=>true
|
24
42
|
end
|
25
43
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
connection.create_table(:contract_workers, :force=>true) do |t|
|
32
|
-
t.references :company
|
33
|
-
t.references :contractor
|
34
|
-
t.string :status
|
44
|
+
class Blog < ActiveRecord::Base
|
45
|
+
belongs_to :person
|
46
|
+
belongs_to :asset, :polymorphic=>true
|
47
|
+
has_many :comments
|
35
48
|
end
|
36
|
-
|
37
|
-
|
38
|
-
t.
|
49
|
+
|
50
|
+
cx.create_table(:comments, :force=>true) do |t|
|
51
|
+
t.references :person
|
52
|
+
t.references :blog
|
53
|
+
t.string :content
|
39
54
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
55
|
+
|
56
|
+
class Comment < ActiveRecord::Base
|
57
|
+
belongs_to :person
|
58
|
+
belongs_to :blog
|
43
59
|
end
|
44
|
-
|
45
|
-
|
46
|
-
t.string :
|
47
|
-
t.
|
60
|
+
|
61
|
+
cx.create_table(:images, :force=>true) do |t|
|
62
|
+
t.string :caption
|
63
|
+
t.integer :size
|
48
64
|
end
|
49
65
|
|
50
|
-
|
51
|
-
|
52
|
-
t.references :document, :polymorphic=>true
|
53
|
-
t.text :comment
|
54
|
-
t.string :status
|
66
|
+
class Image < ActiveRecord::Base
|
67
|
+
has_one :blog, :as=>:asset
|
55
68
|
end
|
56
|
-
|
57
|
-
|
58
|
-
t.string :
|
69
|
+
|
70
|
+
cx.create_table(:recordings, :force=>true) do |t|
|
71
|
+
t.string :title
|
72
|
+
t.integer :duration
|
59
73
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
74
|
+
|
75
|
+
class Recording < ActiveRecord::Base
|
76
|
+
has_one :blog, :as=>:asset
|
63
77
|
end
|
78
|
+
|
79
|
+
|
80
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jeff Patmon
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-04 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|