updateclass (Vapor::RepositoryManager)

    # File vapor/repositorymgr.rb, line 386
        def updateclass( new_klassdef )
          raise TypeError unless new_klassdef.is_a? ClassMetaData

          old_klassdef = known_classes().find{|k| k.name == new_klassdef.name }

          # check if the class is known to the repository
          raise ClassNotKnownError unless old_klassdef

          # check if superclass still the same
          unless old_klassdef.superclass == new_klassdef.superclass
            raise InvalidMetadataError, "different superclass `#{new_klassdef.superclass}' for `#{new_klassdef.name}'"
          end

          # get the class' oid
          oid = @dbh.select_one( %!SELECT _oid FROM ":Vapor::ClassMetaData" WHERE _name = '#{old_klassdef.name}' ! )[0]

          # let's check out each attribute
          new_klassdef.attributes.each{|new_attr|
            # search for same name field
            old_attr = old_klassdef.attributes.find{|a| a.name == new_attr.name }
            if !old_attr.nil? # an attribute with same name exists
              if old_attr == new_attr then # skip it if it's exactly same
               next
              else                         # changing not allowed
               raise InvalidMetadataError, "can't change type of defined attribute `#{old_attr.name}'"
             end
            end # !old_attr.nil?

            ### new attribute not in the class' attribute list, must be new

            ## attempt to modify the table(s)
            begin
              @dbh.execute( %!ALTER TABLE "#{old_klassdef.table}" ADD COLUMN "#{new_attr.name}" #{new_attr.type_sql}! )
              @dbh.execute( %!ALTER TABLE "_#{old_klassdef.table}" ADD COLUMN "#{new_attr.name}" #{new_attr.type_sql}! )
            rescue DBI::ProgrammingError => e
              case e.message
              when %!ALTER TABLE: column.*already exists in table "#{old_klassdef.table}"!  # redefining a parent class's attribute
                raise InvalidMetadataError, "can't override attribute `#{new_attr.name}' defined in superclass"
              when %!ALTER TABLE: column.*already exists in table "(\w+)"! # defining attribute in child class
                raise InvalidMetadataError, "creation of attribute `#{new_attr.name}' with same name as attribute defined in child class `#{$~[1]}' not supported by PostgreSQL 7.2"
              else
                raise e
              end
            end

            ## add to metadata

            # insert attribute
            @dbh.execute( %!INSERT INTO ":Vapor::AttributeMetaData" (_oid, _name, _type, _array ) VALUES ( #{oid}, '#{new_attr.name}', '#{new_attr.type_s}', #{new_attr.is_array} )! )
          } # new_klassdef.attributes.each

          ## update indexes by first dropping all and then (re)creating them

          # drop non-unique indexes (common method to PostgreSQL 7.2 and 7.3)
          @dbh.execute( %!SELECT i.relname FROM pg_index index, pg_class r, pg_class i WHERE r.relname = '#{old_klassdef.table}' AND index.indisprimary = false AND index.indisunique = false AND r.oid = index.indrelid AND index.indexrelid = i.oid! ).each{|index|
            @dbh.execute( %!DROP INDEX "#{index[0]}"! )
          }

          # drop unique indexes (method dependent on PostgreSQL version)
          @dbh.execute( %!SELECT i.relname FROM pg_index index, pg_class r, pg_class i WHERE r.relname = '#{old_klassdef.table}' AND index.indisprimary = false AND index.indisunique = true AND r.oid = index.indrelid AND index.indexrelid = i.oid! ).each{|index|

            if @psql_version >= "7.3"
              @dbh.execute( %!ALTER TABLE "#{old_klassdef.table}" DROP CONSTRAINT "#{index[0]}"! )
            else  # PostgreSQL 7.2
              @dbh.execute( %!DROP INDEX "#{index[0]}"! )
            end
          }

          index_number = 0
          new_klassdef.indexes.each{|index|
            create_index( new_klassdef.name, index_number, index, false )
            index_number += 1
          }
          new_klassdef.unique.each{|index|
            create_index( new_klassdef.name, index_number, index, true )
            index_number += 1
          }

        end