lib/og/store/kirby.rb in og-0.26.0 vs lib/og/store/kirby.rb in og-0.27.0
- old
+ new
@@ -32,10 +32,16 @@
end
end
def initialize(options)
super
+
+ @typemap = {
+ :Fixnum => :Integer,
+ :TrueClass => :Boolean
+ }
+
mode = options[:mode] || :local
if mode == :client
# Use a client/server configuration.
@conn = KirbyBase.new(:client, options[:address], options[:port])
@@ -60,14 +66,18 @@
def enchant(klass, manager)
klass.send :attr_accessor, :oid
klass.send :alias_method, :recno, :oid
klass.send :alias_method, :recno=, :oid=
+ unless klass.properties.include? :recno
+ klass.property :recno, Fixnum
+ end
+
symbols = klass.properties.keys
klass.module_eval %{
- def self.kb_create(recno, #{symbols.join(', ')})
+ def self.kb_create(#{symbols.join(', ')})
obj = self.allocate
obj.recno = recno
#{ symbols.map { |s| "obj.#{s} = #{s}; "} }
return obj
end
@@ -156,42 +166,113 @@
def sql_update(sql)
# nop, not supported.
end
+ def join(obj1, obj2, table, options = nil)
+ first, second = join_object_ordering(obj1, obj2)
+ @conn.get_table(table.to_sym).insert(first.pk, second.pk)
+ end
+
+ def unjoin(obj1, obj2, table)
+ first, second = join_object_ordering(obj1, obj2)
+
+ @conn.get_table(table.to_sym).delete do |r|
+ require 'dev-utils/debug'
+ breakpoint
+ r.send(:first_key) == first.pk and
+ r.send(:second_key) == second.pk
+ end
+ end
+
private
+ def typemap(key)
+ @typemap[key] || key
+ end
+
def create_table(klass)
- fields = fields_for_class(klass)
- begin
+ if @conn.table_exists?(klass.table.to_sym)
+ get_table(klass).pack # Kirby specific method of database cleanup.
+
+ field_names = field_names_for_class(klass)
+ actual_fields = get_table(klass).field_names
+
+ field_names.each do |needed_field|
+ next if actual_fields.include?(needed_field)
+
+ if @options[:evolve_schema] == true
+ Logger.debug "Adding field '#{needed_field}' to '#{klass.table}'"
+ field_type = typemap(klass.properties[needed_field].klass.name.to_sym)
+ if get_table(klass).respond_to?(:add_column)
+ get_table(klass).add_column(needed_field, field_type)
+ else
+ @conn.add_table_column(klass.table, needed_field, field_type)
+ end
+ else
+ Logger.warn "Table '#{klass.table}' is missing field '#{needed_field}' and :evolve_schema is not set to true!"
+ end
+ end
+
+ actual_fields.each do |obsolete_field|
+ next if field_names.include?(obsolete_field)
+
+ if @options[:evolve_schema] == true and @options[:evolve_schema_cautious] == false
+ Logger.debug "Removing obsolete field '#{obsolete_field}' from '#{klass.table}'"
+ if get_table(klass).respond_to?(:drop_column)
+ get_table(klass).drop_column(obsolete_field)
+ else
+ @conn.drop_table_column(klass.table, obsolete_field)
+ end
+ else
+ Logger.warn "You have an obsolete field '#{obsolete_field}' on table '#{klass.table}' and :evolve_schema is not set or is in cautious mode!"
+ end
+ end
+ else
+ Logger.debug "Creating table '#{klass.table}'"
+ fields = fields_for_class(klass)
table = @conn.create_table(klass.table.to_sym, *fields) do |t|
t.record_class = klass
end
- rescue Object => ex
- # gmosx: any idea how to better test this?
- if ex.to_s =~ /already exists/i
- Logger.debug "Table for '#{klass}' already exists!"
- return
- else
- raise
+ end
+
+=begin
+ # Create join tables if needed. Join tables are used in
+ # 'many_to_many' relations.
+
+ if join_tables = klass.ann.self[:join_tables]
+ for info in join_tables
+ unless @conn.table_exists?(info[:table].to_sym)
+ @conn.create_table(info[:table].to_sym, *create_join_table_sql(info))
+ Logger.debug "Created jointable '#{info[:table]}'."
+ end
end
end
+=end
end
+
+ def create_join_table_sql(join_info)
+ [join_info[:first_key].to_sym, :Integer, join_info[:second_key].to_sym, :Integer]
+ end
+
def drop_table(klass)
@conn.drop_table(klass.table) if @conn.table_exists?(klass.table)
end
+ def field_names_for_class(klass)
+ klass.properties.values.map {|p| p.symbol }
+ end
+
def fields_for_class(klass)
fields = []
klass.properties.values.each do |p|
klass.index(p.symbol) if p.index
fields << p.symbol
- type = p.klass.name.to_sym
- type = :Integer if type == :Fixnum
+ type = typemap(p.klass.name.to_sym)
fields << type
end
return fields