lib/rtm/ontopia.rb in rtm-ontopia-0.2.1 vs lib/rtm/ontopia.rb in rtm-ontopia-0.3.0

- old
+ new

@@ -1,55 +1,78 @@ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig. # License: Apache License, Version 2.0 -if Object.const_defined?("Gem") && rtmgem = Gem.loaded_specs["rtm-ontopia"] - require 'rtm/javatmapi' -else +unless Object.const_defined?("Gem") && rtmgem = Gem.loaded_specs["rtm-ontopia"] javatmapi_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../rtm-javatmapi/lib")) - if File.directory?(javatmapi_path) - $LOAD_PATH.unshift javatmapi_path - require 'rtm/javatmapi' - end + $LOAD_PATH.unshift javatmapi_path if File.directory?(javatmapi_path) end +require 'rtm/javatmapi' Dir[File.join(File.dirname(__FILE__), 'ontopia/javalibs/*.jar')].each {|file| require file } require File.join(File.dirname(__FILE__), '/ontopia/io/to_cxtm') module RTM class Ontopia < JavaTMAPI - require File.join(File.dirname(__FILE__), '/ontopia/rdbms/properties') identifier :ontopia - + def initialize(*args) super - if @params[:store] == :rdbms - # enhance all ontopia properties from rails-style config - ontopia_properties = RTM::Ontopia::Rdbms::Properties.rails2ontopia(@params[:store_config]) - - # FIXME: this works only if properties was not specified as file - @params[:properties] ||= {} - ontopia_properties.each do |k,v| - @params[:properties][k] = v.to_s unless @params[:properties].key?(k) - end - end - tmsf = Java::NetOntopiaTopicmapsImplTmapi2::TopicMapSystemFactory.new set_tmsf(tmsf) set_properties(@params[:properties]) set_features(@params[:features]) create_system end + def self.connect(*args) + params = args.first + + # redirect to create an rdbms connection if an adapter is given and we did not already com from there + if params && params[:adapter] && self != OntopiaRdbms + OntopiaRdbms.connect(*args) + else + # adapter was not given or we already handled it and came back here through super + super + end + end + end + + class OntopiaRdbms < Ontopia + require File.join(File.dirname(__FILE__), '/ontopia/rdbms/properties') + require File.join(File.dirname(__FILE__), '/ontopia/rdbms/store') + identifier :ontopia_rdbms + + def initialize(params={}) + params2 = params || {} # XXX hack: maybe setting params in Engine#initialize is not the best idea + + # enhance all ontopia properties from rails-style config + ontopia_properties = RTM::Ontopia::Rdbms::Properties.rails2ontopia(config(params2)) + + # FIXME: this works only if properties was not specified as file + params2[:properties] ||= {} + ontopia_properties.each do |k,v| + params2[:properties][k] = v.to_s unless params2[:properties].key?(k) + end + super + @params.merge(params2) + end + + def config(params = @params) + # if no config-option is given, use params directly, but clean it up a bit + params[:config] || params.reject{|k,v| k == :identifier || k == :backend || k == :implementation} + end + # Migrate the Database to contain the Ontopia RDBMS schema. Uses the connection data provided with connect def migrate_database - self.class.migrate_database(@params[:store_config]) + self.class.migrate_database(config) end + alias migrate migrate_database # Drops the Ontopia schema from the database. This corresponds to migrating the database down. def migrate_database_down - self.class.migrate_database_down(@params[:store_config]) + self.class.migrate_database_down(config) end # Migrate the Database to contain the Ontopia RDBMS schema. # Uses a Rails-style database configuration hash to connect to the database. # @@ -59,118 +82,147 @@ # :schema_file => directly supply sql file to execute instead of autodetect # :adapter_schema_name => directly supply the schema name (generic, h2, mysql, oracle8, oracle9i, oracle10g, postresql, sqlserver) # :direction => :up|:down create or drop schema (defaults to :up) # def self.migrate_database(config) + res = nil + connect_with(config) do |connection| + # see if we were provided with a schema directly or get it from file + schema_sql = config[:schema_sql] + unless schema_sql + # should we migrate up or down? + direction = config[:direction] || :up + create_or_drop = direction.to_s == "up" ? "create" : "drop" + + # get the adapter name for ontopia from the config + adapter_schema_name = config[:adapter_schema_name] || config[:adapter].sub(/^jdbc/, '') + + # check if it is one of the available adapters + available_schemas = %w[generic h2 mysql oracle8 oracle9i oracle10g postresql sqlserver] + adapter_schema_name = "generic" unless available_schemas.include?(adapter_schema_name) + + # find the corresponding schema file + schema_file = config[:schema_file] || File.join(File.dirname(__FILE__), "/../../res/rdbms/setup/#{adapter_schema_name}.#{create_or_drop}.sql") + raise "Could not find schema definition file #{File.expand_path(schema_file)}." unless File.exist?(schema_file) + + # read the schema + schema_sql = File.read(schema_file) + end + + # execute the schema + res = connection.execute(schema_sql) + end + res + end + + # Drops the Ontopia schema from the database. This corresponds to migrating the database down. + def self.migrate_database_down(params={}) + migrate_database(params.merge(:direction => :down)) + end + + # Provides a given block with a (temporary) connection using the given + # configuration. Either an existing connection is used (and kept open) or + # a new connection is opened, yielded to the block and then closed again. + # + # This is needed for migrations and for the connection check. + # Within the connection check it loads the needed JDBC connectors via + # ActiveRecord. + def self.connect_with(config) require 'active_record' unless defined?(ActiveRecord) require 'jdbc_adapter' unless defined?(ActiveRecord::ConnectionAdapters::Jdbc) - # create a new anonymous class extending ActiveRecord::Base for a separate connection - anonymous_active_record_base = Class.new(ActiveRecord::Base) + # prepare variable for separate connection class (if needed) + anonymous_active_record_base = nil # use a supplied connection or create one using the config connection = config[:connection] unless connection + # create a new anonymous class extending ActiveRecord::Base for a separate connection + anonymous_active_record_base = Class.new(ActiveRecord::Base) + # connect to backend using the anonymous base class anonymous_active_record_base.establish_connection(config) connection = anonymous_active_record_base.connection end - # see if we were provided with a schema directly or get it from file - schema_sql = config[:schema_sql] - unless schema_sql - # should we migrate up or down? - direction = config[:direction] || :up - create_or_drop = direction.to_s == "up" ? "create" : "drop" + yield connection if block_given? - # get the adapter name for ontopia from the config - adapter_schema_name = config[:adapter_schema_name] || config[:adapter].sub(/^jdbc/, '') + # close connection if we created a new one + anonymous_active_record_base.remove_connection if anonymous_active_record_base + end - # check if it is one of the available adapters - available_schemas = %w[generic h2 mysql oracle8 oracle9i oracle10g postresql sqlserver] - adapter_schema_name = "generic" unless available_schemas.include?(adapter_schema_name) - - # find the corresponding schema file - schema_file = config[:schema_file] || File.join(File.dirname(__FILE__), "/../../res/rdbms/setup/#{adapter_schema_name}.#{create_or_drop}.sql") - raise "Could not find schema definition file #{File.expand_path(schema_file)}." unless File.exist?(schema_file) - - # read the schema - schema_sql = File.read(schema_file) + def check + check_ok = false + self.class.connect_with(config) do |connection| + check_ok = true if connection.table_exists?('tm_topic_map') || connection.table_exists?('TM_TOPIC_MAP') # MySQL needs ALLCAPS, but e.g. H2 needs small letters. Dunno why. end - - # execute the schema - connection.execute(schema_sql) + check_ok end - - # Drops the Ontopia schema from the database. This corresponds to migrating the database down. - def self.migrate_database_down(params={}) - migrate_database(params.merge(:direction => :down)) - end end end -Java::OrgTmapiCore::TopicMap.register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl +Java::OrgTmapiCore::TopicMap.register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::TopicMapImpl -module Java::OrgTmapiCore::Topic - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicImpl +module Java::OrgTmapiCore::Topic + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::TopicImpl end module Java::OrgTmapiCore::Association - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::AssociationImpl end -module Java::OrgTmapiCore::Name - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl +module Java::OrgTmapiCore::Name + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::NameImpl end module Java::OrgTmapiCore::Occurrence - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::OccurrenceImpl end module Java::OrgTmapiCore::Variant - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::VariantImpl end module Java::OrgTmapiCore::Role - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::RoleImpl end module Java::OrgTmapiCore::Scoped - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ScopedImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::ScopedImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::AssociationImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::NameImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::OccurrenceImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::VariantImpl end module Java::OrgTmapiCore::Typed - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::AssociationImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::NameImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::OccurrenceImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::RoleImpl end module Java::OrgTmapiCore::Construct - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ConstructImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicMapImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.TopicImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.AssociationImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.NameImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.RoleImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::ConstructImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::TopicMapImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::TopicImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::AssociationImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::NameImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::OccurrenceImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::VariantImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::RoleImpl end module Java::OrgTmapiCore::Reifiable - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.ReifiableImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::ReifiableImpl end -module Java::OrgTmapiCore::Locator - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.LocatorImpl +module Java::OrgTmapiCore::Locator + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::LocatorImpl end module Java::OrgTmapiCore::DatatypeAware - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.DatatypeAwareImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.VariantImpl - register_java_implementation net.ontopia.topicmaps.impl.tmapi2.OccurrenceImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::DatatypeAwareImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::VariantImpl + register_java_implementation Java::NetOntopiaTopicmapsImplTmapi2::OccurrenceImpl end