Class: Engine2::TypeInfo

Inherits:
Object show all
Defined in:
lib/engine2/type_info.rb

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ TypeInfo

Returns a new instance of TypeInfo.



7
8
9
10
# File 'lib/engine2/type_info.rb', line 7

def initialize model
    @model = model
    @info = model.type_info
end

Instance Method Details

#any_field(field) ⇒ Object



48
49
50
51
# File 'lib/engine2/type_info.rb', line 48

def any_field field
    define_field field, :any do |info|
    end
end

#blob_field(field, length) ⇒ Object



60
61
62
63
64
# File 'lib/engine2/type_info.rb', line 60

def blob_field field, length
    define_field field, :blob do |info|
        info[:length] = length
    end
end

#blob_store_field(name, name_field, mime_field) ⇒ Object



272
273
274
275
276
277
278
279
280
# File 'lib/engine2/type_info.rb', line 272

def blob_store_field name, name_field, mime_field
    optional name
    define_field :"#{name}_blob", :blob_store do |info|
        info[:bytes_field] = name
        info[:name_field] = name_field
        info[:mime_field] = mime_field
        info[:transaction] = true
    end
end

#boolean(field, true_value = 1, false_value = 0) ⇒ Object



77
78
79
80
81
82
83
84
# File 'lib/engine2/type_info.rb', line 77

def boolean field, true_value = 1, false_value = 0
    modify_field field do |info|
        info[:type] = :boolean
        info[:true_value] = true_value
        info[:false_value] = false_value
        info[:validations][:boolean] = true
    end
end

#boolean_field(field) ⇒ Object



72
73
74
75
# File 'lib/engine2/type_info.rb', line 72

def boolean_field field
    define_field field, :boolean do |info|
    end
end

#currency(field, symbol = ) ⇒ Object



264
265
266
267
268
269
270
# File 'lib/engine2/type_info.rb', line 264

def currency field, symbol = LOCS[:currency_symbol]
    modify_field field do |info|
        info[:type] = :currency
        info[:symbol] = symbol
        info[:validations][:currency] = true
    end
end

#date_field(field, format, model_format) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/engine2/type_info.rb', line 86

def date_field field, format, model_format
    define_field field, :date do |info|
        info[:format] = format
        info[:model_format] = model_format
        info[:validations][:date] = true
    end
end

#date_range(from, to) ⇒ Object



247
248
249
250
251
252
253
254
# File 'lib/engine2/type_info.rb', line 247

def date_range from, to
    depends_on(from, to)
    modify_field from do |info|
        # info[:type] = :date_range
        info[:other_date] = to
        info[:validations][:date_range] = true
    end
end

#date_time(date, time) ⇒ Object



256
257
258
259
260
261
262
# File 'lib/engine2/type_info.rb', line 256

def date_time date, time
    depends_on(date, time)
    modify_field date do |info|
        info[:other_time] = time
        info[:validations][:date_time] = true
    end
end

#datetime_field(field, date_format, time_format, date_model_format, time_model_format) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/engine2/type_info.rb', line 109

def datetime_field field, date_format, time_format, date_model_format, time_model_format
    define_field field, :datetime do |info|
        info[:date_format] = date_format
        info[:time_format] = time_format
        info[:date_model_format] = date_model_format
        info[:time_model_format] = time_model_format
        info[:validations][:datetime] = true
    end
end

#decimal_date(field, format = , model_format = "yyyyMMdd") ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/engine2/type_info.rb', line 134

def decimal_date field, format = LOCS[:default_date_format], model_format = "yyyyMMdd"
    modify_field field do |info|
        info[:type] = :decimal_date
        info[:format] = format
        info[:model_format] = model_format
        info[:validations][:decimal_date] = true
    end
end

#decimal_field(field, size, scale) ⇒ Object



119
120
121
122
123
124
125
126
127
# File 'lib/engine2/type_info.rb', line 119

def decimal_field field, size, scale
    define_field field, :decimal do |info|
        info[:validations][:decimal] = {
            scale: scale,
            size: size,
            regexp: (scale && size) ? /^\d{,#{size - scale}}(?:\.\d{,#{scale}})?$/ : nil
        }
    end
end

#decimal_time(field, format = , model_format = "HHmmss", model_regexp = /^(\d{2})(\d{2})(\d{2})$/) ⇒ Object



143
144
145
146
147
148
149
150
151
# File 'lib/engine2/type_info.rb', line 143

def decimal_time field, format = LOCS[:default_time_format], model_format = "HHmmss", model_regexp = /^(\d{2})(\d{2})(\d{2})$/
    modify_field field do |info|
        info[:type] = :decimal_time
        info[:format] = format
        info[:model_format] = model_format
        info[:model_regexp] = model_regexp
        info[:validations][:decimal_time] = true
    end
end

#decode(name, dinfo = {form: {scaffold: true}, search: {scaffold: true}}) ⇒ Object



345
346
347
348
349
350
351
352
353
# File 'lib/engine2/type_info.rb', line 345

def decode name, dinfo = {form: {scaffold: true}, search: {scaffold: true}}
    modify_field name do |info|
        raise E2Error.new("Field type of '#{name}' in model '#{@model}' needs to be 'many_to_one'") unless info[:type] == :many_to_one
        dec = info[:decode] ||= {}
        dec[:search].clear if dinfo[:search] && dec[:search]
        dec[:form].clear if dinfo[:form] && dec[:form]
        info[:decode].rmerge!(dinfo)
    end
end

#default(field, value) ⇒ Object



153
154
155
156
157
# File 'lib/engine2/type_info.rb', line 153

def default field, value
    modify_field field do |info|
        info[:default] = value
    end
end

#define_field(field, type) {|info| ... } ⇒ Object

Yields:

  • (info)

Raises:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/engine2/type_info.rb', line 12

def define_field field, type
    info = @info[field]
    raise E2Error.new("Field '#{field}' already defined in model '#{@model}'") if info && info[:type]

    unless info
        @info[field] = info = {dummy: true}
        @model.dummies << field
    end

    info.merge!({
        name: field,
        otype: type,
        type: type,
        validations: {}
    })
    yield info
end

#depends_on(what, *on) ⇒ Object



36
37
38
39
40
# File 'lib/engine2/type_info.rb', line 36

def depends_on what, *on
    modify_field what do |info|
        (info[:depends] ||= []).concat(on)
    end
end

#dont_strip(field) ⇒ Object



178
179
180
181
182
# File 'lib/engine2/type_info.rb', line 178

def dont_strip field
    modify_field field do |info|
        info[:dont_strip] = true
    end
end

#email(field, message = ) ⇒ Object



214
215
216
217
218
219
# File 'lib/engine2/type_info.rb', line 214

def email field, message = LOCS[:invalid_email_format]
    modify_field field do |info|
        info[:type] = :email
    end
    format field, /\w+\@\w+\.\w+/, message
end

#file_store_field(field, multiple = true, table = :files, store = {}) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/engine2/type_info.rb', line 227

def file_store_field field, multiple = true, table = :files, store = {}
    # string_field field, 1000
    any_field field
    modify_field field do |info|
        info[:type] = :file_store
        info[:multiple] = multiple
        info[:table] = table
        info[:store] = store
        info[:store][:upload] ||= "#{Engine2::SETTINGS[:path]}/store/upload"
        info[:store][:files] ||= "#{Engine2::SETTINGS[:path]}/store/files"
        info[:transaction] = true
    end
end

#fix_decimal(field, size, scale) ⇒ Object



190
191
192
193
194
195
196
197
198
# File 'lib/engine2/type_info.rb', line 190

def fix_decimal field, size, scale
    modify_field field do |info|
        info[:validations][:decimal] = {
            scale: scale,
            size: size,
            regexp: /^\d{,#{size - scale}}(?:\.\d{,#{scale}})?$/
        }
    end
end

#foreign_blob_store_field(assoc_name, name, name_field, mime_field) ⇒ Object

Raises:



282
283
284
285
286
287
288
289
290
291
292
# File 'lib/engine2/type_info.rb', line 282

def foreign_blob_store_field assoc_name, name, name_field, mime_field
    assoc = @model.many_to_one_associations[assoc_name]
    raise E2Error.new("'many_to_one' association '#{assoc_name}' not found for model '#{@model}'") unless assoc
    define_field :"#{assoc[:key]}_blob", :foreign_blob_store do |info|
        info[:assoc_name] = assoc_name
        info[:bytes_field] = name
        info[:name_field] = name_field
        info[:mime_field] = mime_field
        info[:transaction] = true
    end
end

#format(field, pattern, message = ) ⇒ Object



241
242
243
244
245
# File 'lib/engine2/type_info.rb', line 241

def format field, pattern, message = LOCS[:invalid_format]
    modify_field field do |info|
        info[:validations][:format] = {pattern: pattern, message: message}
    end
end

#integer_field(field) ⇒ Object



66
67
68
69
70
# File 'lib/engine2/type_info.rb', line 66

def integer_field field
    define_field field, :integer do |info|
        info[:validations][:integer] = true
    end
end

#list_select(name, options) ⇒ Object



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/engine2/type_info.rb', line 321

def list_select name, options
    modify_field name do |info|
        info[:type] = :list_select
        values = options[:values]

        if options[:multiselect]
            info[:multiselect] = true
            case info[:otype]
            when :string
                info[:separator] = options[:separator] || ';'
                info[:validations].delete(:string_length)
            when :integer
                info[:validations].delete(:integer)
            end
            info[:max_length] = options[:max_length] || 3
            info[:max_length_html] = options[:max_length_html] || LOCS[:list_select_selected]
        end

        raise E2Error.new("type '#{values.class}' not supported for list_select modifier for field #{name}") unless values.is_a?(Hash)
        info[:values] = values.to_a
        info[:validations][:list_select] = true
    end
end

#list_select_bits(values) ⇒ Object



317
318
319
# File 'lib/engine2/type_info.rb', line 317

def list_select_bits values
    values.each_with_index.map{|a, i|[1 << i, a]}.to_h
end

#many_to_one_field(assoc_name) ⇒ Object

Raises:



294
295
296
297
298
299
300
301
302
303
# File 'lib/engine2/type_info.rb', line 294

def many_to_one_field assoc_name
    assoc = @model.many_to_one_associations[assoc_name]
    raise E2Error.new("'many_to_one' association '#{assoc_name}' not found for model '#{@model}'") unless assoc
    keys = assoc[:keys]
    modify_field keys.first do |info|
        info[:type] = :many_to_one
        info[:keys] = keys
        info[:assoc_name] = assoc_name
    end
end

#modify_field(field) {|info| ... } ⇒ Object

Yields:

  • (info)

Raises:



30
31
32
33
34
# File 'lib/engine2/type_info.rb', line 30

def modify_field field
    info = @info[field]
    raise E2Error.new("No field '#{field}' defined for model '#{@model}'") unless info
    yield info
end

#null_value(field, value) ⇒ Object



42
43
44
45
46
# File 'lib/engine2/type_info.rb', line 42

def null_value field, value
    modify_field field do |info|
        info[:null_value] = value
    end
end

#optional(field) ⇒ Object



167
168
169
170
171
172
# File 'lib/engine2/type_info.rb', line 167

def optional field
    modify_field field do |info|
        info.delete(:required)
        info[:optional] = true
    end
end

#optionals(*fields) ⇒ Object



174
175
176
# File 'lib/engine2/type_info.rb', line 174

def optionals *fields
    fields.each{|f|optional f}
end

#password(field) ⇒ Object



221
222
223
224
225
# File 'lib/engine2/type_info.rb', line 221

def password field
    modify_field field do |info|
        info[:type] = :password
    end
end

#primary_key(field) ⇒ Object



184
185
186
187
188
# File 'lib/engine2/type_info.rb', line 184

def primary_key field
    modify_field field do |info|
        info[:primary_key] = true
    end
end

#required(field, message = , &blk) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/engine2/type_info.rb', line 159

def required field, message = LOCS[:field_required], &blk
    modify_field field do |info|
        raise E2Error.new("Required condition already provided for field #{field} in model #{@model}") if blk && info[:required] && info[:required][:if]
        info[:required] = {message: message}
        info[:required][:if] = blk if blk
    end
end

#sequence(name, seq_name) ⇒ Object



362
363
364
365
366
# File 'lib/engine2/type_info.rb', line 362

def sequence name, seq_name
    modify_field name do |info|
        info[:sequence] = seq_name
    end
end

#star_to_many_field(assoc_name, schemes = Schemes::STMF_LINK) ⇒ Object

Raises:



305
306
307
308
309
310
311
312
313
314
315
# File 'lib/engine2/type_info.rb', line 305

def star_to_many_field assoc_name, schemes = Schemes::STMF_LINK
    assoc = @model.one_to_many_associations[assoc_name] || @model.many_to_many_associations[assoc_name]
    raise E2Error.new("'*_to_many' association '#{assoc_name}' not found for model '#{@model}'") unless assoc
    define_field assoc_name, :string do |info|
        info[:type] = :star_to_many_field
        info[:schemes] = schemes
        info[:keys] = assoc[:keys]
        info[:assoc_name] = assoc_name
        info[:transaction] = true
    end
end

#string_field(field, length) ⇒ Object



53
54
55
56
57
58
# File 'lib/engine2/type_info.rb', line 53

def string_field field, length
    define_field field, :string do |info|
        info[:length] = length
        info[:validations][:string_length] = true
    end
end

#text_field(field) ⇒ Object



129
130
131
132
# File 'lib/engine2/type_info.rb', line 129

def text_field field
    define_field field, :text do |info|
    end
end

#time(field, format, model_format) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/engine2/type_info.rb', line 100

def time field, format, model_format
    modify_field field do |info|
        info[:type] = :time
        info[:format] = format
        info[:model_format] = model_format
        info[:validations][:time] = true
    end
end

#time_field(field, format, model_format) ⇒ Object



94
95
96
97
98
# File 'lib/engine2/type_info.rb', line 94

def time_field field, format, model_format
    define_field field, :time do |info|
    end
    time field, format, model_format
end

#unique(field, *with) ⇒ Object

def validation field, name, opts = true

modify_field field do |info|
    info[:validations][name] = opts
end

end



206
207
208
209
210
211
212
# File 'lib/engine2/type_info.rb', line 206

def unique field, *with
    depends_on(field, *with)
    modify_field field do |info|
        info[:transaction] = true
        info[:validations][:unique] = {with: with}
    end
end

#validate(name, validation_name = nil, &blk) ⇒ Object

Raises:



355
356
357
358
359
360
# File 'lib/engine2/type_info.rb', line 355

def validate name, validation_name = nil, &blk
    raise E2Error.new("Local validation '#{validation_name}' in model '#{@model}' conflicts with builtin validation") if validation_name && Validations[validation_name]
    modify_field name do |info|
        info[:validations][validation_name || :"#{@model.table_name}_#{name}_#{info[:validations].size}"] = {lambda: blk}
    end
end