square-arel 2.0.9.20110222133018
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/.autotest +26 -0
- data/History.txt +105 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +124 -0
- data/README.markdown +94 -0
- data/Rakefile +20 -0
- data/lib/arel.rb +39 -0
- data/lib/arel/attributes.rb +20 -0
- data/lib/arel/attributes/attribute.rb +18 -0
- data/lib/arel/compatibility/wheres.rb +33 -0
- data/lib/arel/crud.rb +37 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/deprecated.rb +4 -0
- data/lib/arel/expression.rb +4 -0
- data/lib/arel/expressions.rb +23 -0
- data/lib/arel/insert_manager.rb +34 -0
- data/lib/arel/nodes.rb +53 -0
- data/lib/arel/nodes/and.rb +6 -0
- data/lib/arel/nodes/as.rb +6 -0
- data/lib/arel/nodes/assignment.rb +6 -0
- data/lib/arel/nodes/avg.rb +6 -0
- data/lib/arel/nodes/between.rb +6 -0
- data/lib/arel/nodes/binary.rb +12 -0
- data/lib/arel/nodes/count.rb +13 -0
- data/lib/arel/nodes/delete_statement.rb +19 -0
- data/lib/arel/nodes/does_not_match.rb +6 -0
- data/lib/arel/nodes/equality.rb +9 -0
- data/lib/arel/nodes/except.rb +7 -0
- data/lib/arel/nodes/exists.rb +7 -0
- data/lib/arel/nodes/function.rb +18 -0
- data/lib/arel/nodes/greater_than.rb +6 -0
- data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
- data/lib/arel/nodes/group.rb +6 -0
- data/lib/arel/nodes/grouping.rb +6 -0
- data/lib/arel/nodes/having.rb +6 -0
- data/lib/arel/nodes/in.rb +6 -0
- data/lib/arel/nodes/inner_join.rb +6 -0
- data/lib/arel/nodes/insert_statement.rb +19 -0
- data/lib/arel/nodes/intersect.rb +7 -0
- data/lib/arel/nodes/join.rb +13 -0
- data/lib/arel/nodes/less_than.rb +6 -0
- data/lib/arel/nodes/less_than_or_equal.rb +6 -0
- data/lib/arel/nodes/limit.rb +7 -0
- data/lib/arel/nodes/lock.rb +6 -0
- data/lib/arel/nodes/matches.rb +6 -0
- data/lib/arel/nodes/max.rb +6 -0
- data/lib/arel/nodes/min.rb +6 -0
- data/lib/arel/nodes/node.rb +44 -0
- data/lib/arel/nodes/not.rb +6 -0
- data/lib/arel/nodes/not_equal.rb +6 -0
- data/lib/arel/nodes/not_in.rb +6 -0
- data/lib/arel/nodes/offset.rb +7 -0
- data/lib/arel/nodes/on.rb +6 -0
- data/lib/arel/nodes/or.rb +6 -0
- data/lib/arel/nodes/ordering.rb +20 -0
- data/lib/arel/nodes/outer_join.rb +6 -0
- data/lib/arel/nodes/select_core.rb +26 -0
- data/lib/arel/nodes/select_statement.rb +22 -0
- data/lib/arel/nodes/sql_literal.rb +8 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/sum.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +13 -0
- data/lib/arel/nodes/top.rb +6 -0
- data/lib/arel/nodes/unary.rb +11 -0
- data/lib/arel/nodes/union.rb +7 -0
- data/lib/arel/nodes/union_all.rb +7 -0
- data/lib/arel/nodes/unqualified_column.rb +16 -0
- data/lib/arel/nodes/update_statement.rb +21 -0
- data/lib/arel/nodes/values.rb +14 -0
- data/lib/arel/predications.rb +183 -0
- data/lib/arel/relation.rb +6 -0
- data/lib/arel/select_manager.rb +237 -0
- data/lib/arel/sql/engine.rb +10 -0
- data/lib/arel/sql_literal.rb +4 -0
- data/lib/arel/table.rb +134 -0
- data/lib/arel/tree_manager.rb +36 -0
- data/lib/arel/update_manager.rb +49 -0
- data/lib/arel/visitors.rb +38 -0
- data/lib/arel/visitors/depth_first.rb +154 -0
- data/lib/arel/visitors/dot.rb +230 -0
- data/lib/arel/visitors/join_sql.rb +40 -0
- data/lib/arel/visitors/mssql.rb +16 -0
- data/lib/arel/visitors/mysql.rb +34 -0
- data/lib/arel/visitors/oracle.rb +116 -0
- data/lib/arel/visitors/order_clauses.rb +11 -0
- data/lib/arel/visitors/postgresql.rb +58 -0
- data/lib/arel/visitors/sqlite.rb +11 -0
- data/lib/arel/visitors/to_sql.rb +331 -0
- data/lib/arel/visitors/visitor.rb +27 -0
- data/lib/arel/visitors/where_sql.rb +9 -0
- data/square-arel.gemspec +36 -0
- data/test/attributes/test_attribute.rb +664 -0
- data/test/helper.rb +13 -0
- data/test/nodes/test_as.rb +16 -0
- data/test/nodes/test_count.rb +18 -0
- data/test/nodes/test_delete_statement.rb +14 -0
- data/test/nodes/test_equality.rb +74 -0
- data/test/nodes/test_insert_statement.rb +18 -0
- data/test/nodes/test_node.rb +33 -0
- data/test/nodes/test_not.rb +20 -0
- data/test/nodes/test_or.rb +22 -0
- data/test/nodes/test_select_core.rb +22 -0
- data/test/nodes/test_select_statement.rb +13 -0
- data/test/nodes/test_sql_literal.rb +52 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_update_statement.rb +18 -0
- data/test/support/fake_record.rb +91 -0
- data/test/test_activerecord_compat.rb +18 -0
- data/test/test_attributes.rb +46 -0
- data/test/test_crud.rb +69 -0
- data/test/test_delete_manager.rb +42 -0
- data/test/test_insert_manager.rb +125 -0
- data/test/test_select_manager.rb +659 -0
- data/test/test_table.rb +193 -0
- data/test/test_update_manager.rb +86 -0
- data/test/visitors/test_depth_first.rb +212 -0
- data/test/visitors/test_dot.rb +29 -0
- data/test/visitors/test_join_sql.rb +35 -0
- data/test/visitors/test_mssql.rb +18 -0
- data/test/visitors/test_mysql.rb +45 -0
- data/test/visitors/test_oracle.rb +147 -0
- data/test/visitors/test_postgres.rb +36 -0
- data/test/visitors/test_sqlite.rb +18 -0
- data/test/visitors/test_to_sql.rb +255 -0
- metadata +261 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
module Arel
|
2
|
+
class SelectManager < Arel::TreeManager
|
3
|
+
include Arel::Crud
|
4
|
+
|
5
|
+
def initialize engine, table = nil
|
6
|
+
super(engine)
|
7
|
+
@ast = Nodes::SelectStatement.new
|
8
|
+
@ctx = @ast.cores.last
|
9
|
+
from table
|
10
|
+
end
|
11
|
+
|
12
|
+
def taken
|
13
|
+
@ast.limit && @ast.limit.expr
|
14
|
+
end
|
15
|
+
|
16
|
+
def constraints
|
17
|
+
@ctx.wheres
|
18
|
+
end
|
19
|
+
|
20
|
+
def skip amount
|
21
|
+
@ast.offset = Nodes::Offset.new(amount)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
###
|
26
|
+
# Produces an Arel::Nodes::Exists node
|
27
|
+
def exists
|
28
|
+
Arel::Nodes::Exists.new @ast
|
29
|
+
end
|
30
|
+
|
31
|
+
def where_clauses
|
32
|
+
#warn "where_clauses is deprecated" if $VERBOSE
|
33
|
+
to_sql = Visitors::ToSql.new @engine
|
34
|
+
@ctx.wheres.map { |c| to_sql.accept c }
|
35
|
+
end
|
36
|
+
|
37
|
+
def lock locking = Arel.sql('FOR UPDATE')
|
38
|
+
case locking
|
39
|
+
when true
|
40
|
+
locking = Arel.sql('FOR UPDATE')
|
41
|
+
when Arel::Nodes::SqlLiteral
|
42
|
+
when String
|
43
|
+
locking = Arel.sql locking
|
44
|
+
end
|
45
|
+
|
46
|
+
@ast.lock = Nodes::Lock.new(locking)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def locked
|
51
|
+
@ast.lock
|
52
|
+
end
|
53
|
+
|
54
|
+
def on *exprs
|
55
|
+
@ctx.froms.constraint = Nodes::On.new(collapse(exprs))
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def group *columns
|
60
|
+
columns.each do |column|
|
61
|
+
# FIXME: backwards compat
|
62
|
+
column = Nodes::SqlLiteral.new(column) if String === column
|
63
|
+
column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column
|
64
|
+
|
65
|
+
@ctx.groups.push Nodes::Group.new column
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def from table
|
71
|
+
table = Nodes::SqlLiteral.new(table) if String === table
|
72
|
+
# FIXME: this is a hack to support
|
73
|
+
# test_with_two_tables_in_from_without_getting_double_quoted
|
74
|
+
# from the AR tests.
|
75
|
+
if @ctx.froms
|
76
|
+
source = @ctx.froms
|
77
|
+
|
78
|
+
if Nodes::SqlLiteral === table && Nodes::Join === source
|
79
|
+
source.left = table
|
80
|
+
table = source
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
@ctx.froms = table
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def join relation, klass = Nodes::InnerJoin
|
89
|
+
return self unless relation
|
90
|
+
|
91
|
+
case relation
|
92
|
+
when String, Nodes::SqlLiteral
|
93
|
+
raise if relation.blank?
|
94
|
+
from Nodes::StringJoin.new(@ctx.froms, relation)
|
95
|
+
else
|
96
|
+
from klass.new(@ctx.froms, relation, nil)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def having expr
|
101
|
+
expr = Nodes::SqlLiteral.new(expr) if String === expr
|
102
|
+
|
103
|
+
@ctx.having = Nodes::Having.new(expr)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def project *projections
|
108
|
+
# FIXME: converting these to SQLLiterals is probably not good, but
|
109
|
+
# rails tests require it.
|
110
|
+
@ctx.projections.concat projections.map { |x|
|
111
|
+
[Symbol, String].include?(x.class) ? SqlLiteral.new(x.to_s) : x
|
112
|
+
}
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
def order *expr
|
117
|
+
# FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
|
118
|
+
@ast.orders.concat expr.map { |x|
|
119
|
+
String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
|
120
|
+
}
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
def orders
|
125
|
+
@ast.orders
|
126
|
+
end
|
127
|
+
|
128
|
+
def wheres
|
129
|
+
Compatibility::Wheres.new @engine, @ctx.wheres
|
130
|
+
end
|
131
|
+
|
132
|
+
def where_sql
|
133
|
+
return if @ctx.wheres.empty?
|
134
|
+
|
135
|
+
viz = Visitors::WhereSql.new @engine
|
136
|
+
Nodes::SqlLiteral.new viz.accept @ctx
|
137
|
+
end
|
138
|
+
|
139
|
+
def union operation, other = nil
|
140
|
+
if other
|
141
|
+
node_class = Nodes.const_get("Union#{operation.to_s.capitalize}")
|
142
|
+
else
|
143
|
+
other = operation
|
144
|
+
node_class = Nodes::Union
|
145
|
+
end
|
146
|
+
|
147
|
+
node_class.new self.ast, other.ast
|
148
|
+
end
|
149
|
+
|
150
|
+
def intersect other
|
151
|
+
Nodes::Intersect.new ast, other.ast
|
152
|
+
end
|
153
|
+
|
154
|
+
def except other
|
155
|
+
Nodes::Except.new ast, other.ast
|
156
|
+
end
|
157
|
+
alias :minus :except
|
158
|
+
|
159
|
+
def take limit
|
160
|
+
@ast.limit = Nodes::Limit.new(limit)
|
161
|
+
@ctx.top = Nodes::Top.new(limit)
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
def join_sql
|
166
|
+
return nil unless @ctx.froms
|
167
|
+
|
168
|
+
viz = Visitors::JoinSql.new @engine
|
169
|
+
Nodes::SqlLiteral.new viz.accept @ctx
|
170
|
+
end
|
171
|
+
|
172
|
+
def order_clauses
|
173
|
+
Visitors::OrderClauses.new(@engine).accept(@ast).map { |x|
|
174
|
+
Nodes::SqlLiteral.new x
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
def joins manager
|
179
|
+
if $VERBOSE
|
180
|
+
warn "joins is deprecated and will be removed in 2.2"
|
181
|
+
warn "please remove your call to joins from #{caller.first}"
|
182
|
+
end
|
183
|
+
manager.join_sql
|
184
|
+
end
|
185
|
+
|
186
|
+
class Row < Struct.new(:data) # :nodoc:
|
187
|
+
def id
|
188
|
+
data['id']
|
189
|
+
end
|
190
|
+
|
191
|
+
def method_missing(name, *args)
|
192
|
+
name = name.to_s
|
193
|
+
return data[name] if data.key?(name)
|
194
|
+
super
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def to_a # :nodoc:
|
199
|
+
warn "to_a is deprecated. Please remove it from #{caller[0]}"
|
200
|
+
# FIXME: I think `select` should be made public...
|
201
|
+
@engine.connection.send(:select, to_sql, 'AREL').map { |x| Row.new(x) }
|
202
|
+
end
|
203
|
+
|
204
|
+
# FIXME: this method should go away
|
205
|
+
def insert values
|
206
|
+
im = InsertManager.new @engine
|
207
|
+
table = @ctx.froms
|
208
|
+
primary_key_name = (primary_key = table.primary_key) && primary_key.name
|
209
|
+
# FIXME: in AR tests values sometimes were Array and not Hash therefore is_a?(Hash) check is added
|
210
|
+
primary_key_value = primary_key && values.is_a?(Hash) && values[primary_key]
|
211
|
+
im.into table
|
212
|
+
im.insert values
|
213
|
+
# Oracle adapter needs primary key name to generate RETURNING ... INTO ... clause
|
214
|
+
# for tables which assign primary key value using trigger.
|
215
|
+
# RETURNING ... INTO ... clause will be added only if primary_key_value is nil
|
216
|
+
# therefore it is necessary to pass primary key value as well
|
217
|
+
@engine.connection.insert im.to_sql, 'AREL', primary_key_name, primary_key_value
|
218
|
+
end
|
219
|
+
|
220
|
+
private
|
221
|
+
def collapse exprs
|
222
|
+
exprs.map! { |x| x.class == ::String ? Arel.sql(x) : x }
|
223
|
+
|
224
|
+
return exprs.first if exprs.length == 1
|
225
|
+
|
226
|
+
right = exprs.pop
|
227
|
+
left = exprs.pop
|
228
|
+
|
229
|
+
right = Nodes::SqlLiteral.new(right) if String === right
|
230
|
+
|
231
|
+
right = Nodes::And.new left, right
|
232
|
+
exprs.reverse.inject(right) { |memo,expr|
|
233
|
+
Nodes::And.new(expr, memo)
|
234
|
+
}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
data/lib/arel/table.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
module Arel
|
2
|
+
class Table
|
3
|
+
include Arel::Crud
|
4
|
+
|
5
|
+
@engine = nil
|
6
|
+
class << self; attr_accessor :engine; end
|
7
|
+
|
8
|
+
attr_accessor :name, :engine, :aliases, :table_alias
|
9
|
+
|
10
|
+
def initialize name, engine = Table.engine
|
11
|
+
@name = name.to_s
|
12
|
+
@engine = engine
|
13
|
+
@columns = nil
|
14
|
+
@aliases = []
|
15
|
+
@table_alias = nil
|
16
|
+
@primary_key = nil
|
17
|
+
|
18
|
+
if Hash === engine
|
19
|
+
@engine = engine[:engine] || Table.engine
|
20
|
+
@columns = attributes_for engine[:columns]
|
21
|
+
|
22
|
+
# Sometime AR sends an :as parameter to table, to let the table know
|
23
|
+
# that it is an Alias. We may want to override new, and return a
|
24
|
+
# TableAlias node?
|
25
|
+
@table_alias = engine[:as] unless engine[:as].to_s == @name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_key
|
30
|
+
@primary_key ||= begin
|
31
|
+
primary_key_name = @engine.connection.primary_key(name)
|
32
|
+
# some tables might be without primary key
|
33
|
+
primary_key_name && self[primary_key_name]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def alias name = "#{self.name}_2"
|
38
|
+
Nodes::TableAlias.new(name, self).tap do |node|
|
39
|
+
@aliases << node
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def from table
|
44
|
+
SelectManager.new(@engine, table)
|
45
|
+
end
|
46
|
+
|
47
|
+
def joins manager
|
48
|
+
if $VERBOSE
|
49
|
+
warn "joins is deprecated and will be removed in 2.2"
|
50
|
+
warn "please remove your call to joins from #{caller.first}"
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def join relation, klass = Nodes::InnerJoin
|
56
|
+
return from(self) unless relation
|
57
|
+
|
58
|
+
case relation
|
59
|
+
when String, Nodes::SqlLiteral
|
60
|
+
raise if relation.blank?
|
61
|
+
from Nodes::StringJoin.new(self, relation)
|
62
|
+
else
|
63
|
+
from klass.new(self, relation, nil)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def group *columns
|
68
|
+
from(self).group(*columns)
|
69
|
+
end
|
70
|
+
|
71
|
+
def order *expr
|
72
|
+
from(self).order(*expr)
|
73
|
+
end
|
74
|
+
|
75
|
+
def where condition
|
76
|
+
from(self).where condition
|
77
|
+
end
|
78
|
+
|
79
|
+
def project *things
|
80
|
+
from(self).project(*things)
|
81
|
+
end
|
82
|
+
|
83
|
+
def take amount
|
84
|
+
from(self).take amount
|
85
|
+
end
|
86
|
+
|
87
|
+
def skip amount
|
88
|
+
from(self).skip amount
|
89
|
+
end
|
90
|
+
|
91
|
+
def having expr
|
92
|
+
from(self).having expr
|
93
|
+
end
|
94
|
+
|
95
|
+
def columns
|
96
|
+
@columns ||=
|
97
|
+
attributes_for @engine.connection.columns(@name, "#{@name} Columns")
|
98
|
+
end
|
99
|
+
|
100
|
+
def [] name
|
101
|
+
return nil unless table_exists?
|
102
|
+
|
103
|
+
name = name.to_sym
|
104
|
+
columns.find { |column| column.name == name }
|
105
|
+
end
|
106
|
+
|
107
|
+
def select_manager
|
108
|
+
SelectManager.new(@engine)
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def attributes_for columns
|
114
|
+
return nil unless columns
|
115
|
+
|
116
|
+
columns.map do |column|
|
117
|
+
Attributes.for(column).new self, column.name.to_sym, column
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def table_exists?
|
122
|
+
@table_exists ||= tables.key?(@name) || engine.connection.table_exists?(name)
|
123
|
+
end
|
124
|
+
|
125
|
+
def tables
|
126
|
+
self.class.table_cache(@engine)
|
127
|
+
end
|
128
|
+
|
129
|
+
@@table_cache = nil
|
130
|
+
def self.table_cache engine # :nodoc:
|
131
|
+
@@table_cache ||= Hash[engine.connection.tables.map { |x| [x,true] }]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Arel
|
2
|
+
class TreeManager
|
3
|
+
# FIXME: Remove this.
|
4
|
+
include Arel::Relation
|
5
|
+
|
6
|
+
attr_accessor :visitor
|
7
|
+
attr_reader :ast, :engine
|
8
|
+
|
9
|
+
def initialize engine
|
10
|
+
@engine = engine
|
11
|
+
@visitor = Visitors.visitor_for @engine
|
12
|
+
@ctx = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_dot
|
16
|
+
Visitors::Dot.new.accept @ast
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_sql
|
20
|
+
@visitor.accept @ast
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_copy other
|
24
|
+
super
|
25
|
+
@ast = @ast.clone
|
26
|
+
end
|
27
|
+
|
28
|
+
def where expr
|
29
|
+
if Arel::TreeManager === expr
|
30
|
+
expr = expr.ast
|
31
|
+
end
|
32
|
+
@ctx.wheres << expr
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Arel
|
2
|
+
class UpdateManager < Arel::TreeManager
|
3
|
+
def initialize engine
|
4
|
+
super
|
5
|
+
@ast = Nodes::UpdateStatement.new
|
6
|
+
@ctx = @ast
|
7
|
+
end
|
8
|
+
|
9
|
+
def take limit
|
10
|
+
@ast.limit = Nodes::Limit.new(limit) if limit
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def order *expr
|
15
|
+
@ast.orders = expr
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
###
|
20
|
+
# UPDATE +table+
|
21
|
+
def table table
|
22
|
+
@ast.relation = table
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def wheres= exprs
|
27
|
+
@ast.wheres = exprs
|
28
|
+
end
|
29
|
+
|
30
|
+
def where expr
|
31
|
+
@ast.wheres << expr
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def set values
|
36
|
+
if String === values
|
37
|
+
@ast.values = [values]
|
38
|
+
else
|
39
|
+
@ast.values = values.map { |column,value|
|
40
|
+
Nodes::Assignment.new(
|
41
|
+
Nodes::UnqualifiedColumn.new(column),
|
42
|
+
value
|
43
|
+
)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
self
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|