module RestCreate

Public Instance Methods

create_database(type: 'plocal', database: logger.progname = 'RestCreate click to toggle source

Creates a database with the given name and switches to this database as working-database. Types are either 'plocal' or 'memory'

Returns the name of the working-database

# File lib/rest/create.rb, line 11
def create_database type: 'plocal', database: 
        logger.progname = 'RestCreate#CreateDatabase'
        old_d = ActiveOrient.database
        ActiveOrient.database_classes = {} 
        ActiveOrient.database = database 
                begin
                        response = ActiveOrient.db_pool.checkout do | conn |
                                 conn["database/#{ActiveOrient.database}/#{type}"].post ""
                        end
                        if response.code == 200
                                logger.info{"Database #{ActiveOrient.database} successfully created and stored as working database"}
                        else
                                logger.error{"Database #{ActiveOrient.database} was NOT created. Working Database is still #{ActiveOrient.database}"}
                                ActiveOrient.database = old_d
                        end
                rescue RestClient::InternalServerError => e
                        logger.error{"Database #{ActiveOrient.database} was NOT created. Working Database is still #{ActiveOrient.database}"}
                        ActiveOrient.database = old_d
                end
                ActiveOrient.database  # return_value
end
create_document(o_class, attributes: {})
Alias for: create_record
create_index(o_class, name:, on: :automatic, type: :unique) click to toggle source

Used to create an index

# File lib/rest/create.rb, line 268
def create_index o_class, name:, on: :automatic, type: :unique
  logger.progname = 'RestCreate#CreateIndex'
    c = classname o_class
                      if  execute( transaction: false, tolerated_error_code: /found duplicated key/) do
                              if on == :automatic
                                      "CREATE INDEX #{c}.#{name} #{type.to_s.upcase}"
                              elsif on.is_a? Array
                                      "CREATE INDEX #{name} ON #{c}(#{on.join(', ')}) #{type.to_s.upcase}"
                              else
                                      "CREATE INDEX #{name} ON #{c}(#{on.to_s}) #{type.to_s.upcase}"
                              end
                      end

                      logger.info{"Index on #{c} based on #{name} created."}
                      else
                              logger.error {"index #{name}.#{type} on  #{c}  NOT created"}
                      end
      end
create_properties(o_class, all_properties) { || ... } click to toggle source

Creates properties

and (if defined in the provided block) associates an index

create_properties(classname or class, properties as hash){index}

The default-case

create_properties(:my_high_sophisticated_database_class,
            con_id: {type: :integer},
            details: {type: :link, linked_class: 'Contracts'}) do
              contract_idx: :notunique
            end

A composite index

create_properties(:my_high_sophisticated_database_class,
            con_id: {type: :integer},
            symbol: {type: :string}) do
        {name: 'indexname',
                     on: [:con_id, :details]    # default: all specified properties
                     type: :notunique            # default: :unique
        }
            end
# File lib/rest/create.rb, line 195
        def create_properties o_class, all_properties, &b
                logger.progname = 'RestCreate#CreateProperties'
                all_properties_in_a_hash = Hash.new  #WithIndifferentAccess.new
                all_properties.each{|field, args| all_properties_in_a_hash.merge! translate_property_hash(field, args)}
                count, response = 0, nil
#               puts "all_properties_in_a_hash #{all_properties_in_a_hash.to_json}"
                if all_properties_in_a_hash.is_a?(Hash)
                        begin
                                response = ActiveOrient.db_pool.checkout do | conn |
                                         conn["/property/#{ActiveOrient.database}/#{classname(o_class)}"].post all_properties_in_a_hash.to_json
                                end
                                        #                          puts response.inspect
                                        # response.body.to_i returns  response.code, only to_f.to_i returns the correct value
                                        count= response.body.to_f.to_i if response.code == 201
                        rescue RestClient::InternalServerError => e
                                logger.progname = 'RestCreate#CreateProperties'
                                response = JSON.parse(e.response)['errors'].pop
                                error_message = response['content'].split(':').last
                                logger.error{"Properties in #{classname(o_class)} were NOT created"}
                                logger.error{"The Error was: #{response['content'].split(':').last}"}
                                nil
                        end
                end
                ### index
                if block_given?# && count == all_properties_in_a_hash.size
                        index = yield
                        if index.is_a?(Hash)
                                if index.size == 1
                                        create_index o_class, name: index.keys.first, on: all_properties_in_a_hash.keys, type: index.values.first
                                else
                                        index_hash =  {type: :unique, on: all_properties_in_a_hash.keys}.merge index
                                        create_index o_class,  name: index_hash[:name], on: index_hash[:on], type: index_hash[:type]
                                end
                        end
                end
                count  # return_value
        end
create_property(o_class, field, index: nil, **args) { || ... } click to toggle source

Create a single property.

Supported types: orientdb.com/docs/last/SQL-Create-Property.html

If an index is to be specified, it's defined in the optional block

create_property(class, field){:unique | :notunique}
# File lib/rest/create.rb, line 247
def create_property o_class, field, index: nil, **args, &b
        logger.progname = 'RestCreate#CreateProperty'
        args= { type: :string} if args.blank?  # the default case
        c = create_properties o_class, {field => args}
        if index.nil? && block_given?
                index = yield
        end
        if index.present?
                if index.is_a?(String) || index.is_a?(Symbol)
                        create_index o_class, name: field, type: index
                elsif index.is_a? Hash
                        bez = index.keys.first
                        create_index o_class, name: bez, type: index[bez], on: [field]
                end
        end
end
create_record(o_class, attributes: {}) { || ... } click to toggle source

Creates a Record in the Database and returns this as ActiveOrient::Model-Instance

Creates a Record with the attributes provided in the attributes-hash e.g.

create_record @classname, attributes: {con_id: 343, symbol: 'EWTZ'}

Puts the database-response into the cache by default

Argument: silence

if silence is specified, no Error-Messages are raised. Instead 

      * if a record failes to be created, because an index-error occured,  it is replaced by that specified in the database response
# File lib/rest/create.rb, line 97
def create_record o_class, attributes: {}, cache: true, silence: true    # use Model#create instead
  logger.progname = 'RestCreate#CreateRecord'
  attributes = yield if attributes.empty? && block_given?
  # @class must not quoted! Quote only attributes(strings)
  post_argument = {'@class' => classname(o_class)}.merge(attributes.to_orient)
              response = nil
  begin
                      response = ActiveOrient.db_pool.checkout do | conn |
                              conn["/document/#{ActiveOrient.database}"].post post_argument.to_json
                      end
    data = JSON.parse(response.body)
    the_object = ActiveOrient::Model.orientdb_class(name: data['@class']).new data ## return_value
    if cache 
                              ActiveOrient::Base.store_rid( the_object ) 
    else
                              the_object
    end
  rescue RestClient::InternalServerError => e
    sentence=  JSON.parse( e.response)['errors'].last['content']
    if sentence =~ /found duplicated key/
                              raise "Duplicate Key" unless silence
                              rid = sentence.split("#").last
                              logger.info{ "found duplicated Key --> loaded #{rid} instead of creating "}
                              ## reading database content -- maybe update attributes?
                              get_record rid
                      else
                              response = JSON.parse(e.response)['errors'].pop
                              logger.error{response['content'].split(':')[1..-1].join(':')}
                              logger.error{"No Object allocated"}
                              nil # return_value
                      end
  rescue Errno::EADDRNOTAVAIL => e
    sleep(2)
    retry
  end
end
Also aliased as: create_document
upsert(o_class, set: , where: logger.progname = 'RestCreate click to toggle source

update or insert one record is implemented as upsert. The where-condition is merged into the set-attributes if its a hash.

Otherwise it's taken unmodified.

The method returns the included or the updated dataset

## to do # yield works for updated and for inserted datasets # upsert ( ) do | what, record | # if what == :insert # do stuff with insert # if what == :update # do stuff with update # end # returns nil if no insert and no update was made, ie. the dataset is identical to the given attributes

# File lib/rest/create.rb, line 160
def upsert o_class, set: , where:    #    use Model#Upsert instead
        logger.progname = 'RestCreate#Upsert'
        specify_return_value =  "return after @rid"
        #                     set.merge! where if where.is_a?( Hash ) # copy where attributes to set
        command = "Update #{classname(o_class)} set #{generate_sql_list( set ){','}} upsert #{specify_return_value}  #{compose_where where}" 
        result = execute( tolerated_error_code: /found duplicated key/){ command }    
#      puts "result #{result.inspect}"
        result =result.pop if result.is_a? Array
end

Private Instance Methods

create_this_class(*db_classname) { || ... } click to toggle source

This is the historic method CreateClasses. It's just performing the database-stuff and now private

it takes superclass and abstract (a hash) as block

usually, only one classname is provided, however the method takes a row of classnames as argument

todo reintegrate the ability to create abstract classes

# File lib/rest/create.rb, line 46
def create_this_class  *db_classname  #nodoc#
        if block_given?
                additional_args =     yield
                superclass = additional_args[ :superclass ]
                abstract = additional_args[ :abstract ].presence || nil
        else 
                superclass = nil
                abstract =  nil
        end
        #
         db_classname.map do | database_class |
                c = if superclass.present?
                                        "CREATE CLASS #{database_class} EXTENDS #{superclass}" 
                                else
                                        "CREATE CLASS #{database_class} "
                                end
                c << " ABSTRACT" if abstract.present?
                execute( tolerated_error_code: /already exists/ ){ c }        
        end
    # execute anything as batch, don't roll back in case of an error

#   execute transaction: false, tolerated_error_code: /already exists/ do
#      command
#    end
   
  rescue ArgumentError => e
    logger.error{ e.backtrace.map {|l| "  #{l}\n"}.join  }
  end