# File vapor/repositorymgr.rb, line 187 def addclass( klass ) raise TypeError unless klass.is_a? ClassMetaData raise BackendInconsistentError unless @repository_ok if known_classes().find{|k| k.name == klass.name } then raise DuplicateClassError, "Class #{klass.name} already registered with Repository" end # check superclass if klass.superclass.empty? then supertable = '' else superclass = known_classes().find{|k| k.name == klass.superclass } if superclass.nil? then raise UnknownSuperclassError, "superclass #{klass.superclass} for #{klass.name} not known to Repository" else supertable = superclass.table end end oid = @oid_gen.next_oid # insert into ":Vapor::ClassMetaData" result = @dbh.execute( %!INSERT INTO ":Vapor::ClassMetaData" (_oid, _name, _superclass, _table) VALUES ( #{oid}, '#{klass.name}', '#{klass.superclass}', '#{klass.table}' )! ) if result.nil? or result.rows != 1 then raise BackendInconsistentError, "could not insert #{klass.name} into ClassMetaData" end # insert attributes into ":Vapor::AttributeMetaData" klass.attributes.each{|attr| result = @dbh.execute( %!INSERT INTO ":Vapor::AttributeMetaData" (_oid, _name, _type, _array ) VALUES ( #{oid}, '#{attr.name}', '#{attr.type_s}', #{attr.is_array} )! ) if result.nil? or result.rows != 1 then raise BackendInconsistentError, "could not insert #{attr.name} into AttributeMetaData" end } # prepare and create the class' table tabledef = Array.new tabledef << ['_oid', 'BIGINT PRIMARY KEY'] tabledef << ['_revision', 'BIGINT'] tabledef << ['_last_change','BIGINT'] klass.attributes.each{|attr| tabledef << [ "#{attr.name}", attr.type_sql ] } begin # main table: PRIMARY KEY => oid create_table( klass.table, tabledef, supertable, [], klass.indexes, klass.unique ) # historic table: PRIMARY KEY => (oid, revision) tabledef[0] = ['_oid', 'BIGINT'] primkey = ['_oid','_revision'] supertable = "_" + supertable unless supertable.empty? create_table( "_" + klass.table, tabledef, supertable, primkey ) rescue DBI::ProgrammingError => e case e.message when %!CREATE TABLE.*attribute.*\"(\S+)\".*type conflict! raise InvalidMetadataError, "can't override attribute #{$~[1]} defined in superclass" when %!ERROR.*no.*default operator class.*btree! raise InvalidMetadataError, "array tyes can't be part of uniqueness constraints due to Datastore restrictions" else raise e end end # we know this class, don't we known_classes() << klass # finally update Repository modification date @dbh.execute( %!UPDATE ":Vapor::RepositoryInfo" SET value = '#{Time.now.to_s}' WHERE name = 'last-modified'! ) end