Module: Spider::Model

Defined in:
lib/spiderfw/model/sync.rb,
lib/spiderfw/model/type.rb,
lib/spiderfw/model/model.rb,
lib/spiderfw/model/query.rb,
lib/spiderfw/model/storage.rb,
lib/spiderfw/model/element.rb,
lib/spiderfw/model/request.rb,
lib/spiderfw/model/junction.rb,
lib/spiderfw/model/condition.rb,
lib/spiderfw/model/query_set.rb,
lib/spiderfw/model/model_hash.rb,
lib/spiderfw/model/base_model.rb,
lib/spiderfw/model/query_funcs.rb,
lib/spiderfw/model/mixins/tree.rb,
lib/spiderfw/model/proxy_model.rb,
lib/spiderfw/model/mixins/list.rb,
lib/spiderfw/model/unit_of_work.rb,
lib/spiderfw/model/inline_model.rb,
lib/spiderfw/model/storage/db/db.rb,
lib/spiderfw/model/mixins/mixins.rb,
lib/spiderfw/model/active_record.rb,
lib/spiderfw/model/storage/schema.rb,
lib/spiderfw/model/mappers/mapper.rb,
lib/spiderfw/model/identity_mapper.rb,
lib/spiderfw/model/mappers/mappers.rb,
lib/spiderfw/model/mixins/converted.rb,
lib/spiderfw/model/mixins/versioned.rb,
lib/spiderfw/model/mappers/db_mapper.rb,
lib/spiderfw/model/integrated_element.rb,
lib/spiderfw/model/mappers/hash_mapper.rb,
lib/spiderfw/model/mixins/synchronized.rb,
lib/spiderfw/model/storage/base_storage.rb,
lib/spiderfw/model/mixins/state_machine.rb,
lib/spiderfw/model/mappers/proxy_mapper.rb,
lib/spiderfw/model/storage/null_storage.rb,
lib/spiderfw/model/storage/db/reflector.rb,
lib/spiderfw/model/storage/db/db_schema.rb,
lib/spiderfw/model/storage/db/db_storage.rb,
lib/spiderfw/model/extended_models/managed.rb,
lib/spiderfw/model/storage/connection_pool.rb,
lib/spiderfw/model/mappers/document_mapper.rb,
lib/spiderfw/model/storage/db/db_connector.rb,
lib/spiderfw/model/storage/db/adapters/mysql.rb,
lib/spiderfw/model/storage/document/document.rb,
lib/spiderfw/model/storage/db/adapters/mssql.rb,
lib/spiderfw/model/storage/db/connectors/jdbc.rb,
lib/spiderfw/model/storage/db/adapters/sqlite.rb,
lib/spiderfw/model/storage/db/connectors/oci8.rb,
lib/spiderfw/model/storage/db/adapters/oracle.rb,
lib/spiderfw/model/storage/db/connectors/odbc.rb,
lib/spiderfw/model/storage/document/document_storage.rb,
lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb,
lib/spiderfw/model/storage/document/adapters/mongodb.rb,
lib/spiderfw/model/storage/db/dialects/no_total_rows.rb

Defined Under Namespace

Modules: ActiveRecordModel, ConditionMixin, Converted, Junction, List, MapperIncludeModule, Mappers, Mixins, StateMachine, Storage, Synchronized, Tree, VersionModel, Versioned Classes: BaseModel, Condition, ConditionContext, Element, FormatError, IdentityMapper, IdentityMapperException, InlineModel, IntegratedElement, Managed, Mapper, MapperElementError, MapperError, MapperTask, ModelException, ModelHash, ProxyModel, Query, QuerySet, Request, SortTask, Sorter, Sync, Type, TypeError, UnitOfWork

Constant Summary

RequiredError =

A required element has no value

MapperElementError.create_subclass(_("Element %s is required"))
NotUniqueError =

An uniqueness constraint has been violated.

MapperElementError.create_subclass(_("Another item with the same %s is already present"))

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) ar_models



299
300
301
# File 'lib/spiderfw/model/active_record.rb', line 299

def self.ar_models
    @ar_models
end

+ (Object) base_type(klass)

Returns the base type corresponding to class. Will walk superclasses and DataType info until a base type is found.



25
26
27
28
29
30
31
# File 'lib/spiderfw/model/model.rb', line 25

def self.base_type(klass)
    k = klass
    while (k && !base_types.include?(k))
        k = simplify_type(k)
    end
    return k
end

+ (Object) base_types

Base types are:

String, Spider::DataTypes::Text, Fixnum, Float, BigDecimal, Date, DateTime, Spider::DataTypes::Bool.

These types must be handled by all mappers.



19
20
21
# File 'lib/spiderfw/model/model.rb', line 19

def self.base_types
    @base_types
end

+ (Object) create_ar_classes(ar, container)



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/spiderfw/model/active_record.rb', line 303

def self.create_ar_classes(ar, container)
    @ar_models ||= []
    return if ar.spider_model
    name = ar.name.split(':')[-1]
    if (container.const_defined?(name))
        current = container.const_get(name)
    end
    unless current
        mod = Class.new(Spider::Model::BaseModel)
        container.const_set(name, mod)
    else
        mod = current
    end
    unless mod.is_a?(ActiveRecordModel)
        mod.instance_eval do
            include ActiveRecordModel
        end
    end
    mod.ar_defined = true unless current
    mod.ar = ar
    ar.spider_model = mod
    ar.reflections.each do |name, reflection|
        begin 
            create_ar_classes(reflection.klass, container) unless reflection.klass.spider_model
            through = reflection.through_reflection.klass
            create_ar_classes(through, container) if through && !through.spider_model
        rescue NameError
        end
    end
    @ar_models << mod
end

+ (Object) get(model, val = nil, set_loaded = false)

Returns the identity-mapped object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/spiderfw/model/model.rb', line 60

def self.get(model, val=nil, set_loaded=false)
    if (val && !val.is_a?(Hash))
        if (model.primary_keys.length == 1)
            val = {model.primary_keys[0].name => val}
        else
            raise ModelException, "Can't get without primary keys"
        end
    end
    if identity_mapper
        return identity_mapper.get(model, val, set_loaded)
    else
        return model.new(val)
    end
end

+ (Object) identity_mapper

:nodoc:



84
85
86
# File 'lib/spiderfw/model/model.rb', line 84

def self.identity_mapper #:nodoc:
    Spider.current[:identity_mapper]
end

+ (Object) identity_mapper=(im)

:nodoc:



88
89
90
# File 'lib/spiderfw/model/model.rb', line 88

def self.identity_mapper=(im) #:nodoc:
    Spider.current[:identity_mapper] = im
end

+ (Object) in_unit(&proc)



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/spiderfw/model/model.rb', line 162

def self.in_unit(&proc)
    uow = self.unit_of_work
    self.start_unit_of_work unless uow
    self.with_identity_mapper do
        yield Spider::Model.unit_of_work
        unless uow
            self.unit_of_work.commit
            self.stop_unit_of_work 
        end
    end
    
end

+ (Object) load_fixtures(file, truncate = false)

Load YAML data



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/spiderfw/model/model.rb', line 219

def self.load_fixtures(file, truncate=false)
    if (file =~ /\.([^\.]+)$/)
        extension = $1
    else
        raise ArgumentError, "Can't determine type of fixtures file #{file}"
    end
    data = {}
    case extension
    when 'yml'
        require 'yaml'
        data = YAML.load_file(file)
    end
     # Ruby 1.9: steps are not needed with ordered hashes
    data = [data] unless data.is_a?(Array)
    loaded = []
    data.each do |step|
        step.each do |mod_name, mod_data|
            mod = const_get_full(mod_name)
            mod.mapper.truncate! if truncate
            mod_data.each do |row|
                h = {}
                row.each do |k, v|
                    if v.is_a?(String)
                        if v[0..1] == '@@'
                            v = v[1..-1]
                        elsif v[0].chr == '@'
                            v = eval(v[1..-1].to_s)
                        end
                    end
                    h[k] = v
                end
                obj = mod.new(h)
                obj.insert
                loaded << obj
            end
        end
    end
    loaded
end

+ (Object) no_context(&proc)



140
141
142
143
144
145
146
147
148
149
# File 'lib/spiderfw/model/model.rb', line 140

def self.no_context(&proc)
    uow = self.unit_of_work
    self.unit_of_work = nil
    im = self.identity_mapper            
    self.identity_mapper = nil
    yield
    self.identity_mapper = im
    self.unit_of_work = uow
    
end

+ (Object) no_identity_mapper(&proc)



133
134
135
136
137
138
# File 'lib/spiderfw/model/model.rb', line 133

def self.no_identity_mapper(&proc)
    im = self.identity_mapper
    self.identity_mapper = nil
    yield
    self.identity_mapper = im
end

+ (Object) no_unit_of_work(&proc)



122
123
124
125
126
127
# File 'lib/spiderfw/model/model.rb', line 122

def self.no_unit_of_work(&proc)
    uow = self.unit_of_work
    self.unit_of_work = nil
    yield
    self.unit_of_work = uow
end

+ (Object) put(obj, check = false)

Puts an object into the IdentityMapper



76
77
78
79
80
81
82
# File 'lib/spiderfw/model/model.rb', line 76

def self.put(obj, check=false)
    if (identity_mapper)
        return identity_mapper.put(obj, check)
    else
        return obj
    end
end

+ (Object) ruby_type(klass)

TODO: remove?



34
35
36
37
38
39
40
41
42
43
# File 'lib/spiderfw/model/model.rb', line 34

def self.ruby_type(klass) #:nodoc:
    map_types = {
        Spider::DataTypes::Text => String,
        Spider::DataTypes::Bool => FalseClass,
        Spider::DataTypes::Binary => String,
        Spider::DataTypes::FilePath => String
    }
    return map_types[klass] if map_types[klass]
    return klass
end

+ (Object) simplify_type(klass)

An iteration in the search for base type.



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/spiderfw/model/model.rb', line 46

def self.simplify_type(klass) #:nodoc:
    map_types = {
        
    }
    return klass if base_types.include?(klass)
    return klass if klass <= Spider::Model::BaseModel
    return t if t = map_types[klass]
    return klass.maps_to if klass.subclass_of?(Spider::DataType) && klass.maps_to
    return klass.superclass if klass.superclass
    return nil
end

+ (Object) sort(models, options = {})



293
294
295
296
297
298
299
# File 'lib/spiderfw/model/model.rb', line 293

def self.sort(models, options={})
    options = {
        :association_dependencies => true
    }.merge(options)
    sorter = Sorter.new(models, options)
    sorter.sort
end

+ (Object) start_unit_of_work



92
93
94
95
# File 'lib/spiderfw/model/model.rb', line 92

def self.start_unit_of_work
    uow = UnitOfWork.new
    uow.start
end

+ (Object) stop_unit_of_work



97
98
99
# File 'lib/spiderfw/model/model.rb', line 97

def self.stop_unit_of_work
    Spider.current[:unit_of_work].stop
end

+ (Object) sync_schema(model_or_app, force = false, options = {})

Syncs the schema with the storage. -- FIXME: this is clearly db specific. Move somewhere else.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/spiderfw/model/model.rb', line 178

def self.sync_schema(model_or_app, force=false, options={}) #:nodoc:
    models = []
    mod = const_get_full(model_or_app)
    if (mod.is_a?(Module) && mod.include?(Spider::App))
        mod.models.each { |m| models << m }
    elsif (mod.subclass_of?(Spider::Model::BaseModel))
        models << mod
    end
    storages = []
    tables = []
    models.each do |m|
        unless (options[:no_sync])
            Spider::Logger.debug("SYNCING #{m}")
            m.mapper.sync_schema(force, options) if m.mapper.respond_to?(:sync_schema)
        end
        if (options[:drop_tables] && m.mapper.respond_to?(:schema))
            storages << m.mapper.storage unless storages.include?(m.mapper.storage)
            tables += m.mapper.schema.get_schemas.keys
        end
    end
    if (options[:drop_tables])
        dt = options[:drop_tables]
        tables.flatten
        storage_tables = {}
        storages.each do |s|
            s.list_tables.each do |t|
                storage_tables[t] = s
            end
        end
        tables_to_drop = []
        storage_tables.each do |table_name, storage|
            if !tables.include?(table_name) && (dt == true || table_name.index(dt) == 0)
                tables_to_drop << table_name
            end
        end
        raise Spider::Model::Mappers::SchemaSyncUnsafeConversion.new(tables_to_drop) unless tables_to_drop.empty?
        tables_to_drop.each{ |t| storage.drop_table(t) }
    end
end

+ (Object) unit_of_work(&proc)

:nodoc:



101
102
103
104
105
106
107
108
109
# File 'lib/spiderfw/model/model.rb', line 101

def self.unit_of_work(&proc) #:nodoc:
    uow = Spider.current[:unit_of_work]
    if !uow
        if proc
            uow = UnitOfWork.new(&proc)
        end
    end
    return uow
end

+ (Object) unit_of_work=(uow)



112
113
114
# File 'lib/spiderfw/model/model.rb', line 112

def self.unit_of_work=(uow)
    Spider.current[:unit_of_work] = uow
end

+ (Boolean) unit_of_work_running?



129
130
131
# File 'lib/spiderfw/model/model.rb', line 129

def self.unit_of_work_running?
    self.unit_of_work && self.unit_of_work.running?
end

+ (Object) with_identity_mapper(&proc)

Executes the block in the context of the main IdentityMapper.



152
153
154
155
156
157
158
159
160
# File 'lib/spiderfw/model/model.rb', line 152

def self.with_identity_mapper(&proc)
    if identity_mapper
        yield identity_mapper
    else
        IdentityMapper.new do |im|
            yield im
        end
    end
end

+ (Object) with_unit_of_work(&proc)



116
117
118
119
120
# File 'lib/spiderfw/model/model.rb', line 116

def self.with_unit_of_work(&proc)
    with_identity_mapper do
        return unit_of_work(&proc)
    end
end

Instance Method Details

- (Object) max(element, condition = nil)

Aggregates #



1135
1136
1137
# File 'lib/spiderfw/model/mappers/mapper.rb', line 1135

def max(element, condition=nil)
    raise "Unimplemented"
end