class HODB

Attributes

connectionName[R]
domain[R]
generate[R]
hfields[R]
modelName[R]
parent[R]
parentModel[R]
sortField[R]
source[R]
table[R]
tableCursor[R]
tmp[R]
toChange[R]
toWrite[R]
type[R]

Public Class Methods

amount(this) click to toggle source

Ci sono diversi modi per creare dei campi virtuali Il primo e' quello di creare una funzione all'interno nel modello es. per creare il campo amount:

self.amount_virtual = HField.magic()

def amount

return price.to_i * 2

end

In realta' se togliamo l'istruzione magic funziona lo stesso ma non si capisce che amount e' un campo del modello

Il secondo e' quello di creare il campo fuori dal modello in modo da avere piu' versatilita' In tal modo posso aggiungere i campi runtime

  • products = Products.new

  • products.amount = HField.virtual(:amount, self) # dove amount e' la funzione e self e' l'oggetto contenente la funzione

Il terzo e' quello di passare direttamente un blocco es.

# File lib/hdb/hdb_test.rb, line 208
def self.amount(this)
  return this.quantity * this.price.to_i 
end
manyToMany() click to toggle source
# File lib/hdb/hdb_test.rb, line 100
def self.manyToMany
  
  models = Models.new
  baby = models.create({name: 'Baby Format', description: 'baby format'})
  family = models.create({name: 'Family Format', description: 'family format'})
  
  categories = Categories.new
  konditorei = categories.create({name: 'KONDITOREI'}).foods_table
  sacher = konditorei.create({name: 'Sacher Torte', description: 'schokolade und marmelade', price: 10})

  sacher_modelds_join = sacher.models_join

  sacher_modelds_join.create({models_id: baby})
  sacher_modelds_join.create({models_id: family})

  categories.writeAll

end
manyToMany_2() click to toggle source
# File lib/hdb/hdb_test.rb, line 119
def self.manyToMany_2

  sacher = Foods.new.findBy_name("Sacher Torte")
  sacher.models_join.rightModel.show

end
manyToMany_3() click to toggle source
# File lib/hdb/hdb_test.rb, line 126
def self.manyToMany_3

  family = Models.new.findBy_name("Family Format")

  margherita = Foods.new.findBy_name("Margherita Baby")
  margherita_models_join = margherita.models_join
  margherita_models_join.create({models_id: family})

  # margherita.writeAll non funzionerebbe perche' non proviene da una create
  # la writeAll deve quindi essere eseguita dalla create radice in questo caso margherita_models_join
  margherita_models_join.writeAll 

end
new(modelName = nil, parents = [], connectionName: "default", domain: {}, generate: true) click to toggle source
# File lib/hdb/hodb.rb, line 85
def initialize(modelName = nil, parents = [], connectionName: "default", domain: {}, generate: true)
  p "modelName: #{modelName}, parents: #{parents}, connectionName = #{connectionName}"
  @generate = generate # if true build the table into db

  @visited = []

  @toWrite = []
  @toChange = []
  @toDelete = []

  @vid = 0 # virtual id

  @tmp = {}
  @type = nil 
  @source = nil
  @domain = domain # it's required for example to group the result of oneToMany relation or manyToMany
  @modelName = modelName
  @connectionName = connectionName
  @parents = [] # pairs of type {ptr: 0x..., referenceFieldName: 'modelname_id'}
  @hfields = {} # hypersonic fields
  @tableFields = nil # fields of table
  @modelFields = nil # fields of table + fields of all parents
  @table = []
  @tableCursor = nil 
  @allParents = nil

  self.setParents(parents)
  self.setSystemFields()

  self.init()

end
newOdb(modelName, connectionName = "default", domain: {}) click to toggle source
# File lib/hdb/hodb.rb, line 133
def self.newOdb(modelName, connectionName = "default", domain: {})
  className = modelName.hcapitalize
  return eval("#{className}.new(connectionName: connectionName, domain: domain)")
end
oneToMany() click to toggle source
# File lib/hdb/hdb_test.rb, line 63
def self.oneToMany
  
  printers = Printers.new
  kitchen = printers.create({name: 'KITCHEN'})
  pizzeria = printers.create({name: 'PIZZERIA'})
  bar = printers.create({name: 'BAR'})
  
  categories = Categories.new
  pizze = categories.create({name: 'PIZZE BABY'}).foods_table
  primi = categories.create({name: 'PRIMI BABY'})
  beverage = categories.create({name: 'BEVERAGE'}).foods_table
  
  pizze.create({name: 'Margherita Baby', description: 'Pomodoro, Mozzarella, Basilico', price: 10, printers_id: pizzeria})
  pizze.create({name: 'Marinara Baby', description: 'Pomodoro, Aglio, Olio', price: 10, printers_id: pizzeria})
  pizze.create({name: 'Capricciosa Baby', description: 'Pomodoro, Mozzarella, Funghi, Olive, Uovo, Piselli, Wurstell', price: 10, printers_id: pizzeria})
  pizze.create({name: 'Capricciosa Baby', description: 'Pomodoro, Mozzarella, Funghi, Olive, Uovo, Piselli, Wurstell', price: 10, printers_id: pizzeria})
  pizze.create({name: 'Napoli Baby', description: 'Pomodoro, Mozzarella, Acciughe', price: 10, printers_id: pizzeria})
  pizze.create({name: 'Taggiasca Baby', description: 'Pomodoro, Mozzarella, Olive', price: 10, printers_id: pizzeria})

  primi.foods_table.create({name: 'Tagliatelle ai Porcini', description: 'Fresh Mushrooms', price: 10, printers_id: kitchen})
  
  primi.name = "PRIMI ITALIANI"
 
  beverage.create({name: 'Coke', description: 'Water and Sugar', price: 2, printers_id: bar})
  
  categories.writeAll

end
oneToOne() click to toggle source
# File lib/hdb/hdb_test.rb, line 92
def self.oneToOne

  margherita = Foods.new.findBy_name("Margherita Baby")
  margherita.printers_id.show   # oneToOne
  margherita.categories_id.show # manyToOne

end
test() click to toggle source
# File lib/hdb/hdb_test.rb, line 223
def self.test
  
  #HDBGenerator.new(true)
  #self.test_save2
  #self.virtualFields
  #return
  HDBGenerator.new(true)
  self.test_1
  self.test_2
  self.test_3
  self.test_4
  self.oneToMany
  self.oneToOne
  self.manyToMany
  self.manyToMany_2
  self.manyToMany_3
  self.test_showCategories
  self.test_save
  self.test_save2
  self.virtualFields 
  #self.test_delete

end
test1() click to toggle source
# File lib/hdb/hodb.rb, line 930
def self.test1
  a = HODB.new({a: 1, b: 2, c: 3})
  a.a = 0
  p a.a
  p a.b
  a.d = 40 # make a variable automatically
  p a.d
end
test2() click to toggle source
# File lib/hdb/hodb.rb, line 939
def self.test2
  odb = HODB.new
  odb.name = HField.text(caption: 'Name', mandatory: true, readonly: false)
  odb.name = "hypersonic"
  p odb.hfields(:name), odb.name
end
test_1() click to toggle source
# File lib/hdb/hdb_test.rb, line 6
def self.test_1
  contacts = Contacts.new
  contacts.create({surname: 'Bonaffini',
                   name: 'Herbert', 
                   address: 'Herbert Strasse', 
                   delivery_address: 'Herbert - Delivery', 
                   invoice_address: 'Herbert - Invoice'})
  contacts.show('hight_red', false)
  contacts.writeAll
  contacts.all
  contacts.show('hight_yellow', false)
end
test_2() click to toggle source
# File lib/hdb/hdb_test.rb, line 19
def self.test_2
  suppliers = Suppliers.new
  suppliers.create({surname: 'Viola', 
                    name: 'Ugo', 
                    address: 'Viola Strasse', 
                    delivery_address: 'Viola - Delivery', 
                    invoice_address: 'Viola - Invoice',
                    company_name: 'VIOLA SPA'})
  suppliers.show('hight_cyan', false)
  suppliers.writeAll
  suppliers.all
  suppliers.show('hight_cyan', false)
end
test_3() click to toggle source
# File lib/hdb/hdb_test.rb, line 33
def self.test_3

  suppliers = Suppliers.new
  supplier = suppliers.findBy_name_and_surname("Mario", "Rossi")
  supplier.show

end
test_4() click to toggle source
# File lib/hdb/hdb_test.rb, line 41
def self.test_4
  foods = Foods.new
  foods.all
  foods.each do |record|
    p record.name
    p record.categories_id.name
  end 

end
test_delete() click to toggle source
# File lib/hdb/hdb_test.rb, line 173
def self.test_delete

  pizze = Categories.new.findBy_name("PIZZE").foods_table
  
  rustica = pizze.create({name: 'Rustica', description: 'Pomodoro, Mozzarella, Olive', price: 10})
  biancaneve = pizze.create({name: 'Biancaneve', description: 'Aglio, Olio', price: 10})
  pizze.show
  capricciosa = Foods.new.findBy_name("Capricciosa")
  pizze.remove(rustica)
  pizze.remove(capricciosa)
  pizze.writeAll

end
test_save() click to toggle source
# File lib/hdb/hdb_test.rb, line 140
def self.test_save

  pizze = Categories.new.findBy_name("PIZZE").foods_table
  pizze.create({name: 'Diavola', description: 'Pomodoro, Mozzarella, Salamino e Peperoncino', price: 10})
  pizze.each do |pizza|
    pizza.price = 1 #Random.rand(10)
    pizza.printers_id = 1
  end
  #pizze.show
  pizze.writeAll
  pizze.saveAll

end
test_save2() click to toggle source
# File lib/hdb/hdb_test.rb, line 154
def self.test_save2

  capricciosa = Foods.new.findBy_name("Capricciosa")
  capricciosa.printers_id.name = "pizzeria"
  #capricciosa.show
  capricciosa.saveAll
 

  puts "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§".red
  pizze = Categories.new.findBy_name("PIZZE")
  pizze.foods_table.each do |pizza|
    pizza.printers_id.name = "pippo"
  end
  #pizze.saveAll
  pizze.ok


end
test_showCategories() click to toggle source
# File lib/hdb/hdb_test.rb, line 51
def self.test_showCategories
 
  categories = Categories.new
  categories.all
  categories.show
  categories.each do |record|
    p record.name
    record.foods_table.show  # polimorfismo runtime
  end 

end
virtualFields() click to toggle source
# File lib/hdb/hdb_test.rb, line 212
def self.virtualFields

  products = Products.new
  products.quantity = HField.virtual { |this| this.categories_id.id.to_i }
  products.amount = HField.virtual(:amount, HODB) # Secondo metodo ma passando il nome della classe essendo statica
  #products.amount = HField.virtual { |this| this.quantity * this.price.to_i } # Terzo metodo
  products.all
  products.show("red", [:id, :quantity, :price, :amount, :score, :random])

end

Public Instance Methods

_remove(record = @tableCursor) click to toggle source
# File lib/hdb/hodb.rb, line 827
def _remove(record = @tableCursor)

  record = record.tableCursor if record.class == HRecordPtr 
  puts "_remove: #{record}".pink
  puts "============================".red
  if (record["id"][0] == "#")
    @parents.each { |parent| record[parent[:referenceFieldName]]._remove }
    @toWrite.delete(record)
    @toChange.delete(record)
  else
    @parents.each do |parent| 
      referenceFieldName = parent[:referenceFieldName]
      id = record[referenceFieldName]
      parent[:ptr].remove(id)
    end
    @toDelete << record   
  end
  @table.delete(record)

end
addField(fieldName, args) click to toggle source
# File lib/hdb/hodb.rb, line 237
def addField(fieldName, args)
  
  field = HField.autoComplete(@modelName, fieldName, args) # For the magic field
  @hfields[fieldName] = field
  hl << "addField: #{fieldName} #{field}"

end
all() click to toggle source
# File lib/hdb/hodb.rb, line 679
def all
  return self.findBy()
end
allModels() click to toggle source
# File lib/hdb/hodb.rb, line 486
def allModels
  result = []
  self.allParents().each { |parent| result << parent.modelName unless result.include?(parent.modelName) }
  return result
end
allParents() click to toggle source
# File lib/hdb/hodb.rb, line 148
def allParents()
  return @allParents if @allParents
  @allParents = [self]
  @parents.each { |parent| @allParents += parent[:ptr].allParents() }
  return @allParents 
end
allRelations() click to toggle source
# File lib/hdb/hodb.rb, line 477
def allRelations
  result = []
  result << hdb(@connectionName).normalizeWhereFormat(@domain) if @domain.class == String or @domain.any?
  @parents.each do |parent|
    result += ["#{@modelName}.#{parent[:referenceFieldName]} = #{parent[:ptr].modelName}.id"] + parent[:ptr].allRelations 
  end
  return result
end
apply() click to toggle source
# File lib/hdb/hodb.rb, line 858
def apply
  puts "************************* apply **********************".pink
  self.writeAll
  self.saveAll
  @parents.each { |parent| parent[:ptr].apply }
  @visited.each do |odb|
    puts "####################################=> #{odb.modelName}".pink
    odb.apply
  end
  @visited.clear
end
columnWidth(fieldName, inheritance = true) click to toggle source
# File lib/hdb/hodb.rb, line 870
def columnWidth(fieldName, inheritance = true)
  
  return @colsWidth[fieldName] if @colsWidth.include?(fieldName)

  maxLength = fieldName.length
  self.each do |row|
    row.eachField(inheritance) do |fieldName, fieldValue|  
      len = fieldValue.to_s.length 
      maxLength = len if maxLength < len and fieldValue.class != HRecordPtr and fieldValue.class > HODB
    end
  end
  
  return @colsWidth[fieldName] = maxLength

end
create(record = {}) click to toggle source
# File lib/hdb/hodb.rb, line 699
def create(record = {})
  defaultRecord = self.defaultRecord(record)
  @parents.each { |parent| defaultRecord[parent[:referenceFieldName]] = parent[:ptr].create(record) }
  @toWrite << defaultRecord
  @table << defaultRecord
  self.last
  return self.recordPtr("parent")
end
data(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 507
def data(fieldName)
  
  fieldName = fieldName.to_s    
  node = self.nodeOfField(fieldName)
  return (node.any?) ? node[0].tableCursor[fieldName] : nil

end
defaultRecord(record) click to toggle source
# File lib/hdb/hodb.rb, line 689
def defaultRecord(record)
  defaultRecord = Marshal.load(Marshal.dump(self.fields()))
  defaultRecord.each { |fieldName, fieldValue| defaultRecord[fieldName.to_s] = self.defaultValue(fieldName) }
  defaultRecord["id"] = "##{@vid+=1}"
  record.each {|fieldName,fieldValue| defaultRecord[fieldName.to_s] = fieldValue if defaultRecord.include?(fieldName.to_s)}
  @domain.each {|fieldName,fieldValue| defaultRecord[fieldName.to_s] = fieldValue if defaultRecord.include?(fieldName.to_s)} if @domain.class == Hash
  puts "#{defaultRecord}".red
  return defaultRecord
end
defaultValue(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 683
def defaultValue(fieldName)
  field = @hfields[fieldName.to_s]
  return nil unless field
  return (field[:default]) ? field[:default] : field.defaultValue()
end
delete(where = "TRUE", ids = nil) click to toggle source
# File lib/hdb/hodb.rb, line 802
def delete(where = "TRUE", ids = nil)
  
  where = self.normalizeWhereFormat(where)

  model = (ids == nil) ? self.allModels.join(', ') : @modelName
  where = (self.allRelations << where).join(' and ') unless ids
  
  @tableCursor = nil
  table = hdb(@connectionName).select("#{modelName}.*").from(model).where(where).execute.table
  return self if table.count == 0

  ids = table.column(:id)
  hdb(@connectionName).delete(@modelName, "id IN (#{ids.join(',')})")

  ids.each { |id| @table.delete(self.ptrOfRecord("id", id)) } 
  
  @parents.each do |parent|
    ids = table.column(parent[:referenceFieldName])
    parent[:ptr].delete("id IN (#{ids.join(',')})", ids)
  end
  return self

end
direction(direction) click to toggle source
# File lib/hdb/hodb.rb, line 546
def direction(direction)
  @executed = false
  @direction = direction
  return self
end
each() { |self| ... } click to toggle source
# File lib/hdb/hodb.rb, line 424
def each
          
  self.execute unless @executed

  self.reset()
  while(self.next) do
    yield(self)
  end

  @tableCursor = nil
  self.init()

end
eachField(inheritance = true) { |fieldName, fieldValue| ... } click to toggle source
# File lib/hdb/hodb.rb, line 446
def eachField(inheritance = true)
  self.fields(inheritance).each do |fieldName, fieldValue|
    fieldValue = self.data(fieldName) 
    fieldValue = eval("self.#{fieldName}") unless fieldValue # si tratta di campi virtual runtime
    yield(fieldName, fieldValue)
  end
end
each_with_index() { |self, i += 1| ... } click to toggle source
# File lib/hdb/hodb.rb, line 438
def each_with_index
  i = -1
  self.each do |record|
    yield(self, i += 1)
  end
end
execute() click to toggle source
# File lib/hdb/hodb.rb, line 672
def execute
  # @executed serve per evitare di chiamare execute nelle istruzioni del tipo:
  # odb.where(filter).orderBy(sortField).direction(sortDirection).pageSize(pageSize).page(page)
  @executed = true
  return self.findBy(@where, nil, orderBy: @orderBy, direction: @direction, pageSize: @pageSize, page: @page)
end
fieldProperty(fieldName, property) click to toggle source
# File lib/hdb/hodb.rb, line 322
def fieldProperty(fieldName, property)
  
  return nil unless fieldName
  hfield = self.hfields()[fieldName.to_s] || self.hfields()[fieldName.to_sym]
  return hfield[property.to_s] || hfield[property.to_sym] if hfield
  return nil

end
fields(inheritance = false) click to toggle source

false: return only fields of table true: return the fields of table + parents fields :false: return only hfields of table :true: return only hfields of table + parents hfields

# File lib/hdb/hodb.rb, line 185
def fields(inheritance = false)

  return inheritance if inheritance.class == Array

  case inheritance
  when true 
    return self.modelFields() 
  when false 
    return self.tableFields()
  when :true
    return self.hfields(:true)
  when :false
    return self.hfields(:false)
  end

end
findBy(where = 'true', ids = nil, orderBy: nil, direction: nil, pageSize: "all", page: 0) click to toggle source

example: findBy({id: 1})

findBy({'c_tables.id': 1}) - I can specify the field of the another table 
findBy({id: 1, name: 'ciao'}) -> c_tables.id = '1' AND c_tables.name = 'ciao' 
The follow statement isn't safe. You can use it, only if the values don't come from forms but they are statics
findBy(["c_tables.id > 0", "c_tables.name = 'ciao'"]) 
The follow statement is safe as the ? syntax and you can use the values from forms
findBy(["c_tables.id > 0", "c_tables.name = #{q(form_field)}"])
# File lib/hdb/hodb.rb, line 642
def findBy(where = 'true', ids = nil, orderBy: nil, direction: nil, pageSize: "all", page: 0)

  return self unless where 
  where = self.normalizeWhereFormat(where)
      
  model = (ids == nil) ? self.allModels.join(', ') : @modelName
  where = (self.allRelations << where).join(' and ') if !ids and where
 
  hdb = hdb(@connectionName).
    select("#{modelName}.*").
    from(model).
    where(where).
    orderBy(orderBy).
    direction(direction).
    execute(pageSize: pageSize, page: page)

  @tableFields = Hash[hdb.fieldNameList()]
  @table = hdb.table.sortByList("id", ids)
  @tableCursor = nil

  return self if @table.count == 0

  @parents.each do |parent|
    ids = @table.column(parent[:referenceFieldName])
    parent[:ptr].findBy("id IN (#{ids.join(',')})", ids)
  end
  return self.next().recordPtr('manyToOne')

end
findByOffLine(where) click to toggle source

findByOffLine({id: 1, name: 'margherita'})

# File lib/hdb/hodb.rb, line 620
def findByOffLine(where)

  tableCursor = @tableCursor 
  self.each do |record|
    return self if where.each do |fieldName, fieldValue| 
      #puts "#{record.valueOfField(fieldName.to_s)} -  #{fieldValue}"
      break if record.valueOfField(fieldName.to_s) != fieldValue 
    end
  end
  self.setTableCursor(tableCursor) # if not found restore the tableCursor value
  return self

end
first() click to toggle source
# File lib/hdb/hodb.rb, line 390
def first
  self.reset
  return self.next
end
init() click to toggle source
# File lib/hdb/hodb.rb, line 528
def init()
  @where = "true"
  @orderBy = "id"
  @pageSize = "all"
  @page = 0
end
inspection(str) click to toggle source
# File lib/hdb/hodb.rb, line 317
def inspection(str)
  puts "=============> #{str}"
  return false
end
last() click to toggle source
# File lib/hdb/hodb.rb, line 395
def last
  @tableCursor = @table.count > 0 ? @table[@table.count - 1] : nil
  return self
end
manyToMany(modelName, joinTable, referenceFieldName, referenceFieldName2) click to toggle source
# File lib/hdb/hodb.rb, line 283
def manyToMany(modelName, joinTable, referenceFieldName, referenceFieldName2)

  odb = self.oneToMany(joinTable, joinTable, referenceFieldName)
  odb.type = 'manyToMany'
  odb.tmp[:referenceFieldName] = referenceFieldName2
  odb.tmp[:rightModelName] = modelName
  return odb

end
manyToOne(modelName, referenceFieldName, type = 'manyToOne') click to toggle source
# File lib/hdb/hodb.rb, line 251
def manyToOne(modelName, referenceFieldName, type = 'manyToOne')
 
  return @tableCursor[modelName] if @tableCursor[modelName]
  id = self.valueOfField(referenceFieldName)
  @tableCursor[modelName] = odb = self.newHODB(modelName, type: type)
  @visited.addIfNotPresent(odb)
  puts "modelName: #{referenceFieldName}".red
  @tableCursor.hprint
  unless id 
    self.setValueOfField(referenceFieldName, odb.recordPtr(type))
    return odb
  end
  @toChange << @tableCursor unless @toChange.include?(@tableCursor)
  return odb.findBy_id(id)
 
end
method_missing(sym, *args, &block) click to toggle source

[[:a, :b, :c], [1, 2, 3]].transpose

> [[:a, 1], [:b, 2], [:c, 3]]

# File lib/hdb/hodb.rb, line 334
def method_missing(sym, *args, &block)
  if sym =~ /^(\w+)=$/
    if args[0].class == HField
      self.addField($1.to_s, args[0])
    elsif self.nodeOfField($1.to_s).any?
      @nodes.each { |node| node.tableCursor[$1.to_s] = args[0] if node.tableCursor }
      @toChange << @tableCursor if (!@toChange.include?(@tableCursor) and @tableCursor) 
    elsif instance_variable_defined?("@#{$1.to_s}") # is required to use attr_reader to setting
      instance_variable_set("@#{$1}", args[0])
    else
      hl.<<("hodb::method_missing: #{$1.to_s} not found", "ERROR")
    end
    return
  elsif sym.to_s =~ /^findBy_(.+)$/
    attrs = $1.split('_and_')
    attrs_with_args = [attrs, args].transpose
    where = Hash[attrs_with_args]
    return self.findBy(where) 
  elsif @hfields[sym.to_s] and @hfields[sym.to_s][:modelNameReference]
    modelName = @hfields[sym.to_s][:modelNameReference]
    type = self.fieldProperty(sym, :type)
    return self.oneToOne(modelName, sym.to_s) if (type == 'oneToOne')
    return self.manyToOne(modelName, sym.to_s) if (type == 'manyToOne')
    referenceFieldName = @hfields[sym.to_s][:referenceFieldName]
    return self.oneToMany(sym.to_s, modelName, referenceFieldName) if (type == 'oneToMany')
    joinTable = @hfields[sym.to_s][:joinTable]
    referenceFieldName2 = @hfields[sym.to_s][:referenceFieldName2]
    return self.manyToMany(modelName, joinTable, referenceFieldName, referenceFieldName2) if (type == 'manyToMany')
  elsif @hfields[sym.to_s] and @hfields[sym.to_s][:type] == 'virtual' 
    return self.virtualField(@hfields[sym.to_s][:object] || self, @hfields[sym.to_s][:functionName], &@hfields[sym.to_s][:block])
  elsif sym =~ /^(\w+)_id$/
    return self.manyToOne($1.to_s, sym.to_s)
  elsif sym =~ /^(\w+)_table$/
    return self.oneToMany(sym.to_s, $1.to_s, "#{@modelName}_id")
  elsif sym =~ /^(\w+)_join$/
    return self.manyToMany($1.to_s, "#{@modelName}_#{$1.to_s}_join", "#{@modelName}_id", "#{$1.to_s}_id")
  elsif @tableCursor and @tableCursor.include?(sym.to_s)
    return @tableCursor[sym.to_s]
  #elsif sym =~ /^(\w+)_virtual$/
  #  return self.virtualField($1.to_s, self, &block)
  else 
    @parents.each do |parent| 
      result = parent[:ptr].method_missing(sym, *args, &block)
      return result if result
    end
  end
  hl.<<("hodb::method_missing: #{sym.to_s} not found", "ERROR")
  return nil
end
modelFields() click to toggle source
# File lib/hdb/hodb.rb, line 160
def modelFields # return all fields
  return @modelFields if @modelFields
  @modelFields = Marshal.load(Marshal.dump(self.tableFields()))
  @parents.each { |parent| @modelFields.merge!(parent[:ptr].modelFields()) }
  return @modelFields
end
modelNameAndFieldName(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 500
def modelNameAndFieldName(fieldName)

  modelName = self.modelNameOfField(fieldName)
  return (modelName) ? "#{modelName}.#{fieldName}" : fieldName

end
modelNameOfField(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 492
def modelNameOfField(fieldName)

  fieldName = fieldName.to_s    
  node = self.nodeOfField(fieldName)
  return (node.any?) ? node[0].modelName : nil

end
newHODB(modelName, type: nil, domain: {}) click to toggle source
# File lib/hdb/hodb.rb, line 122
def newHODB(modelName, type: nil, domain: {})
  _modelName = modelName.to_s.hcapitalize
  #puts "newHODB: #{modelName}"
  p "#{_modelName}.new(connectionName: @connectionName, domain: domain)"
  odb = (Object.const_defined?(_modelName)) ? eval("#{_modelName}.new(connectionName: @connectionName, domain: domain)") : HODB.new(modelName, connectionName: @connectionName, domain: domain)
  odb.source = self
  odb.type = type if type
  return odb

end
next() click to toggle source
# File lib/hdb/hodb.rb, line 411
def next()
  
  index = @tableCursor ? @table.index(@tableCursor) + 1 : 0

  if (index < @table.count)
    @tableCursor = @table[index]
    self.setTableCursor 
    return self
  end
  return nil

end
nodeOfField(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 202
def nodeOfField(fieldName)
  result = self.fields().include?(fieldName) ? [self] : []
  @parents.each { |parent| result += parent[:ptr].nodeOfField(fieldName) }
  return @nodes = result
end
normalizeWhereFormat(where) click to toggle source
# File lib/hdb/hodb.rb, line 516
def normalizeWhereFormat(where)
  
  if where.class == Hash # findBy {'c_tables.id': 1}
    newWhere = {} 
    where.each { |fieldName, fieldValue| newWhere[self.modelNameAndFieldName(fieldName)] = fieldValue }
    where = newWhere
  end
  
  return hdb(@connectionName).normalizeWhereFormat(where)

end
oneToMany(fieldName, modelName, referenceFieldName) click to toggle source
# File lib/hdb/hodb.rb, line 268
def oneToMany(fieldName, modelName, referenceFieldName)
  
  return @tableCursor[fieldName] if @tableCursor[fieldName]
  if(self.id[0] != "#")
    domain = {"#{referenceFieldName}": self.id}
    odb = self.newHODB(modelName, type: 'oneToMany', domain: domain).findBy()
    return  @visited.addIfNotPresent(odb)
  end
  domain = {"#{referenceFieldName}": nil}
  odb = self.newHODB(modelName, type: 'oneToMany', domain: domain)
  @tableCursor[fieldName] = odb
  @visited.addIfNotPresent(odb)
  return odb
end
oneToOne(modelName, referenceFieldName) click to toggle source
# File lib/hdb/hodb.rb, line 245
def oneToOne(modelName, referenceFieldName)
 
  return self.manyToOne(modelName, referenceFieldName, 'oneToOne')

end
orderBy(orderBy) click to toggle source
# File lib/hdb/hodb.rb, line 540
def orderBy(orderBy)
  @executed = false
  orderBy = orderBy.hjoin(', ') if(orderBy.class == Array)
  @orderBy = orderBy
  return self
end
page(page) click to toggle source
# File lib/hdb/hodb.rb, line 556
def page(page)
  @executed = false
  @page = page
  return self
end
pageSize(pageSize) click to toggle source
# File lib/hdb/hodb.rb, line 551
def pageSize(pageSize)
  @executed = false
  @pageSize = pageSize
  return self
end
ptrOfRecord(fieldName, fieldValue) click to toggle source
# File lib/hdb/hodb.rb, line 138
def ptrOfRecord(fieldName, fieldValue)
  
  return fieldValue.tableCursor if fieldValue.class == HRecordPtr # Se si tratta gia' di un ptr a un record lo restituisce
  @table.each do |record|
    return record if record[fieldName.to_s] == fieldValue
  end  
  return nil

end
recordPtr(type = nil) click to toggle source
# File lib/hdb/hodb.rb, line 118
def recordPtr(type = nil)
  return HRecordPtr.new(self, type)
end
remove(recordId = @tableCursor["id"]) click to toggle source

virtual remove => the real removal happens with apply

# File lib/hdb/hodb.rb, line 849
def remove(recordId = @tableCursor["id"])

  puts "remove: #{@modelName} - #{recordId}".yellow
  self.findByOffLine({id: recordId})
  self._remove(@tableCursor)

end
reset() click to toggle source
# File lib/hdb/hodb.rb, line 385
def reset
  @parents.each { |parent| parent[:ptr].reset }
  @tableCursor = nil
end
rightModel() click to toggle source

a_table <–> manyToMany <–> b_table To access to b_table from a_table -> a_table.a_table_b_table_join.rightModel Moreover on right model is unsense call the create function

# File lib/hdb/hodb.rb, line 296
def rightModel
  
  rightModelName = @tmp[:rightModelName]
  return @tableCursor[rightModelName] if @tableCursor[rightModelName]

  ids = @table.column(@tmp[:referenceFieldName]) 
  where = "id IN (#{ids.join(',')})"
  odb = self.newHODB(rightModelName, type: 'rightTable').findBy(where) if (@type == 'manyToMany')
  @visited.addIfNotPresent(odb)
  return @tableCursor[rightModelName] = odb

end
save(values = {}) click to toggle source
# File lib/hdb/hodb.rb, line 766
def save(values = {})
  hl << "********************************* save(#{@type} - #{@modelName}) *********************************"
  #return self unless @toChange.include?(@tableCursor)
  puts "#{values}".red
  @tableCursor.hprint
  @tableCursor.merge!(values)
  @tableCursor["id"] = "#default" if @tableCursor["id"][0] == "#"
  self.setTableCursor(@tableCursor)
  @tableCursor.each do |fieldName, fieldValue| 
    if fieldValue.class <= HODB and (fieldValue.type == 'manyToOne' or fieldValue.type == 'oneToOne')
      puts "call: #{fieldName} - #{fieldValue.domain}".red
      @tableCursor[fieldName] = fieldValue.saveAll().id 
    end
  end
  @parents.each { |parent| parent[:ptr].save(values) }
  # intersect rimuove ad es. i campy oneToMany e i campi inseriti dalla merge! sopra se non fanno parte del @tableCursor
  hdb(@connectionName).update(@modelName, @tableCursor.intersect(self.fields), {id: @tableCursor["id"]})
  @tableCursor.each do |fieldName, fieldValue| 
    if fieldValue.class <= HODB and (fieldValue.type == 'oneToMany' or fieldValue.type == 'manyToMany' or fieldValue.type == 'rightTable')
      p "saveAll".red
      fieldValue.saveAll()
    end
  end
  @toChange.delete(@tableCursor) 
  return self
end
saveAll(values = {}) click to toggle source
# File lib/hdb/hodb.rb, line 793
def saveAll(values = {})
  toChange = @toChange.dup
  toChange.each do |record| 
    @tableCursor = record
    self.save(values)
  end
  return self
end
setParents(parents = []) click to toggle source
# File lib/hdb/hodb.rb, line 218
def setParents(parents = [])
  parents.each do |modelName|
    referenceFieldName = "#{modelName}_id"
    parent = {modelName: modelName, referenceFieldName: referenceFieldName}
    self.addField(referenceFieldName, HField.oneToOne(modelName))  
    #parent[:ptr] = self.newHODB(modelName, domain: @domain)
    parent[:ptr] = self.newHODB(modelName)
    @parents << parent
  end

end
setRecord(record, tableCursor = @tableCursor) click to toggle source
# File lib/hdb/hodb.rb, line 708
def setRecord(record, tableCursor = @tableCursor)
  @toChange << tableCursor unless @toChange.include?(tableCursor)
  record.each do |fieldName, fieldValue| 
    unless self.fields(true).include?(fieldName.to_s)
      hl.<<("hodb::setRecord: #{fieldName.to_s} not found", "ERROR")
      next
    end
    setValueOfField(fieldName.to_s, fieldValue) 
  end
end
setSystemFields() click to toggle source
# File lib/hdb/hodb.rb, line 230
def setSystemFields()
  self.id = HField.primaryKey
  self.created_date = HField.dateTime(default: '#CURRENT_TIMESTAMP', system: true)
  self.updated_date = HField.dateTime(default: '#CURRENT_TIMESTAMP', system: true)
  self.ordering = HField.integer(system: true)
end
setTableCursor(tableCursor = @tableCursor) click to toggle source
# File lib/hdb/hodb.rb, line 400
def setTableCursor(tableCursor = @tableCursor)
  @tableCursor = tableCursor
  @id = @tableCursor["id"]
  @parents.each do |parent|
    parentTableCursor = @tableCursor[parent[:referenceFieldName]]
    parentTableCursor = parent[:ptr].ptrOfRecord("id", parentTableCursor)
    parent[:ptr].setTableCursor(parentTableCursor)
  end
  return self
end
setValueOfField(fieldName, fieldValue) click to toggle source
# File lib/hdb/hodb.rb, line 213
def setValueOfField(fieldName, fieldValue)
  nodes = self.nodeOfField(fieldName)
  nodes.each { |node| node.tableCursor[fieldName] = fieldValue }
end
show(color = 'hight_cyan', inheritance = true) click to toggle source
# File lib/hdb/hodb.rb, line 916
def show(color = 'hight_cyan', inheritance = true)
  @colsWidth = {}
  @parents.each do |parent|
    parent[:ptr].show(color, inheritance) unless (inheritance)
  end
  self.showHeader(color, inheritance) 
  self.each do |row|
    row.eachField(inheritance) do |fieldName, fieldValue|  
      self.showValue(fieldName, fieldValue, 'white')
    end
    puts 
  end
end
showHeader(color, inheritance = true) click to toggle source
# File lib/hdb/hodb.rb, line 897
def showHeader(color, inheritance = true)

  puts
  print eval "' >> #{@modelName.to_s} <<'.#{color}"
  puts
  self.fields(inheritance).each do |fieldName, fieldValue|
    self.showValue(fieldName, "-" * self.columnWidth(fieldName, inheritance), color, '+' )
  end
  puts
  self.fields(inheritance).each do |fieldName, fieldValue|
    self.showValue(fieldName, fieldName, color, '|')
  end
  puts
  self.fields(inheritance).each do |fieldName, fieldValue|
    self.showValue(fieldName, "-" * self.columnWidth(fieldName, inheritance), color, '+' )
  end
  puts
end
showValue(fieldName, fieldValue, color = nil, separator = '|') click to toggle source
# File lib/hdb/hodb.rb, line 886
def showValue(fieldName, fieldValue, color = nil, separator = '|')
  
  fieldValue = fieldValue.object_id if fieldValue.class == HRecordPtr or fieldValue.class <= HODB
  value = " #{fieldValue.to_s.center(self.columnWidth(fieldName))} #{separator}"
  unless color
    print value
  else
    print eval "'#{value}'.#{color}"
  end
end
sortOffLine(fieldName = "id", sortDirection = 'desc', sortMap = []) click to toggle source
# File lib/hdb/hodb.rb, line 562
def sortOffLine(fieldName = "id", sortDirection = 'desc', sortMap = [])
  
  # table = [{id:7, name:'valerio', surname:'bianchi'},
  #          {id:8, name:'mario', surname:'rossi'},
  #          {id:6, name:'laura', surname:'neri'}]
  #
  # table.sort_by { |row| row["name"] } =>
  #          {id:6, name:'laura', surname:'neri'},
  #          {id:8, name:'mario', surname:'rossi'},
  #          {id:7, name:'valerio', surname:'bianchi'}
  # columnSorted = tableSorted.column("id") => [1, 3, 2]
  # idColumn = @table.column("id") => [2, 3, 1]
  # sortMap => [2, 1, 0]
  # A this time to print the records it is enough to scan sortMap
  # The first element to print is @table[2] => @table[1] => @table[0]

  puts "========================================================".red
  puts "=======                sortOffLine               =======".red
  puts "========================================================".red
  puts "currentModelName: #{@modelName}".red
  if sortMap.empty?
    node = self.nodeOfField(fieldName)[0]
    return unless node
    puts "modelName of #{fieldName}: #{node.modelName}".red

    p node.hfields()
    fieldType = node.hfields()[fieldName] ? node.hfields()[fieldName][:type] : nil
    puts "type of #{fieldName}: #{fieldType}" 
    tableSorted = nil
    if fieldType == "integer"
      tableSorted = node.table.sort_by { |row| row[fieldName].to_i }
    elsif fieldType == "float"
      tableSorted = node.table.sort_by { |row| row[fieldName].to_f }
    elsif fieldType == "time"
      tableSorted = node.table.sort_by { |row| row[fieldName].to_time }
    elsif fieldType == "date_time"
      tableSorted = node.table.sort_by { |row| row[fieldName].to_datetime }
    else
      tableSorted = node.table.sort_by { |row| row[fieldName] }
    end

    tableSorted.reverse! if sortDirection == 'asc'

    columnSorted = tableSorted.column("id")
    idColumn = node.table.column("id")
    columnSorted.each_with_index { |value, i| sortMap[i] = idColumn.index(value) }
    p sortMap
  end
    
  @table.sortByPositionList(sortMap)

  @parents.each do |parent|
    parent[:ptr].sortOffLine(nil, sortDirection, sortMap)
  end

end
systemFields(inheritance = false) click to toggle source
# File lib/hdb/hodb.rb, line 167
def systemFields(inheritance = false) 
  return self.hfields(inheritance).select { |fieldName, field| field[:system] }
end
tableFields() click to toggle source
# File lib/hdb/hodb.rb, line 155
def tableFields # return only the fields of table
  self.findBy(:false, []) unless @tableFields # poputate @tableFields
  return @tableFields
end
toFieldTable(inheritance = true) click to toggle source
# File lib/hdb/hodb.rb, line 455
def toFieldTable(inheritance = true)
  
  fieldTable = HSpreadFieldTable.new
  fieldTable.tableName = @modelName

  self.fields(inheritance).each do |fieldName, fieldValue|
    fieldTable.addFieldName(fieldName)
    fieldTable.setFieldCaption(fieldName, fieldName.to_s.hcapitalize)
    fieldType = self.fieldProperty(fieldName.to_s, :type) 
    fieldTable.setFieldType(fieldName, fieldType) if fieldType
  end

  self.each_with_index do |row, i|
    row.eachField(inheritance) do |fieldName, fieldValue|  
      fieldTable.setIntoRecordByFieldName(i, fieldName, fieldValue)
    end
  end

  return fieldTable

end
valueOfField(fieldName) click to toggle source
# File lib/hdb/hodb.rb, line 208
def valueOfField(fieldName)
  nodes = self.nodeOfField(fieldName)
  return (nodes.any?) ? nodes[0].tableCursor[fieldName] : nil
end
virtualField(obj, functionName, &block) click to toggle source
# File lib/hdb/hodb.rb, line 309
def virtualField(obj, functionName, &block)

  return block.call(self) if block
  #hl <<  "obj.#{functionName.to_s}(self)"
  return eval("obj.#{functionName.to_s}(self)") if obj and functionName

end
where(where) click to toggle source
# File lib/hdb/hodb.rb, line 535
def where(where)
  @executed = false
  @where = where
  return self
end
write(values = {}) click to toggle source
# File lib/hdb/hodb.rb, line 720
def write(values = {})
  hl << "********************************* write(#{@type}) *********************************"
  return self unless @toWrite.include?(@tableCursor)
  return self unless values  
  puts "#{values}".red
  @tableCursor.merge!(values)
  @tableCursor["id"] = "#default" if @tableCursor["id"][0] == "#"
  @tableCursor.each do |fieldName, fieldValue| 
    if fieldValue.class == HRecordPtr 
      if fieldValue.type == "parent"
        @tableCursor[fieldName] = fieldValue.write(values).id 
      elsif fieldValue.type == "manyToOne" or fieldValue.type == "oneToOne"
        @tableCursor[fieldName] = fieldValue.write().id 
      elsif fieldValue.type == nil # questo caso non deve verificarsi
        hl.<<("hodb::write: ", "ERROR")
        fieldValue.tableCursor.hprint
      end
    end
  end
  # intersect rimuove ad es. i campy oneToMany e i campi inseriti dalla merge! sopra se non fanno parte del @tableCursor
  @tableCursor["id"] = hdb(@connectionName).insert(@modelName, @tableCursor.intersect(self.fields))
  @tableCursor.each do |fieldName, fieldValue| 
    if fieldValue.class <= HODB and (fieldValue.type == 'oneToMany' or fieldValue.type == 'manyToMany' or fieldValue.type == 'rightTable')
      referenceFieldName = fieldValue.domain.keys[0].to_s
      fieldValue.writeAll({"#{referenceFieldName}" => @tableCursor["id"]})
    end
  end
  @toWrite.delete(@tableCursor) 
  return self
end
writeAll(values = {}) click to toggle source
# File lib/hdb/hodb.rb, line 751
def writeAll(values = {})

  puts "********************* writeAll ********************".pink

  @toDelete.each { |record| self.delete({id: record["id"]}) }
  @toDelete.clear

  toWrite = @toWrite.dup
  toWrite.each do |record| 
    @tableCursor = record
    self.write(values)
  end
  return self
end