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/element.rb,
lib/spiderfw/model/request.rb,
lib/spiderfw/model/storage.rb,
lib/spiderfw/model/junction.rb,
lib/spiderfw/model/condition.rb,
lib/spiderfw/model/query_set.rb,
lib/spiderfw/model/base_model.rb,
lib/spiderfw/model/model_hash.rb,
lib/spiderfw/model/mixins/list.rb,
lib/spiderfw/model/mixins/tree.rb,
lib/spiderfw/model/proxy_model.rb,
lib/spiderfw/model/query_funcs.rb,
lib/spiderfw/model/inline_model.rb,
lib/spiderfw/model/unit_of_work.rb,
lib/spiderfw/model/active_record.rb,
lib/spiderfw/model/mixins/mixins.rb,
lib/spiderfw/model/storage/db/db.rb,
lib/spiderfw/model/mappers/mapper.rb,
lib/spiderfw/model/storage/schema.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/mappers/proxy_mapper.rb,
lib/spiderfw/model/mixins/state_machine.rb,
lib/spiderfw/model/storage/base_storage.rb,
lib/spiderfw/model/storage/db/db_schema.rb,
lib/spiderfw/model/storage/db/reflector.rb,
lib/spiderfw/model/storage/null_storage.rb,
lib/spiderfw/model/storage/db/db_storage.rb,
lib/spiderfw/model/extended_models/managed.rb,
lib/spiderfw/model/mappers/document_mapper.rb,
lib/spiderfw/model/storage/connection_pool.rb,
lib/spiderfw/model/storage/db/db_connector.rb,
lib/spiderfw/model/storage/db/adapters/mssql.rb,
lib/spiderfw/model/storage/db/adapters/mysql.rb,
lib/spiderfw/model/storage/document/document.rb,
lib/spiderfw/model/storage/db/adapters/oracle.rb,
lib/spiderfw/model/storage/db/adapters/sqlite.rb,
lib/spiderfw/model/storage/db/connectors/jdbc.rb,
lib/spiderfw/model/storage/db/connectors/oci8.rb,
lib/spiderfw/model/storage/db/connectors/odbc.rb,
lib/spiderfw/model/storage/db/connectors/jdbc_oracle.rb,
lib/spiderfw/model/storage/db/dialects/no_total_rows.rb,
lib/spiderfw/model/storage/document/adapters/mongodb.rb,
lib/spiderfw/model/storage/document/document_storage.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 collapse

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

.ar_modelsObject



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

def self.ar_models
    @ar_models
end

.base_type(klass) ⇒ Object

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

.base_typesObject

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

.create_ar_classes(ar, container) ⇒ Object



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

.get(model, val = nil, set_loaded = false) ⇒ Object

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

.identity_mapperObject

:nodoc:



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

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

.identity_mapper=(im) ⇒ Object

:nodoc:



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

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

.in_unit(&proc) ⇒ Object



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

.load_fixtures(file, truncate = false) ⇒ Object

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
# 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)
    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
            end
        end
    end
end

.no_context(&proc) ⇒ Object



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

.no_identity_mapper(&proc) ⇒ Object



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

.no_unit_of_work(&proc) ⇒ Object



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

.put(obj, check = false) ⇒ Object

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

.ruby_type(klass) ⇒ Object

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

.simplify_type(klass) ⇒ Object

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

.sort(models, options = {}) ⇒ Object



287
288
289
290
291
292
293
# File 'lib/spiderfw/model/model.rb', line 287

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

.start_unit_of_workObject



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

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

.stop_unit_of_workObject



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

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

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

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

.unit_of_work(&proc) ⇒ Object

: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

.unit_of_work=(uow) ⇒ Object



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

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

.unit_of_work_running?Boolean

Returns:

  • (Boolean)


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

.with_identity_mapper(&proc) ⇒ Object

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

.with_unit_of_work(&proc) ⇒ Object



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

#max(element, condition = nil) ⇒ Object

Aggregates #



1115
1116
1117
# File 'lib/spiderfw/model/mappers/mapper.rb', line 1115

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