# jruby should be run in 1.9 mode # if you are using RVM: # mkdir ~/.rvm/hooks # cat > ~/.rvm/hooks/after_use < lambda { |username, password, host, file| "sed '/^[ \t]*$/d' #{file} | sed '/^--.*$/d' | sqlplus -S -L #{username}/#{password}@#{host}" } private # class helper for defining common database arguments to a Thor command def self.db_method_options method_options :url => :string, :username => :string, :password => :string, :type => :string, :jar => :string, :alias => :string end public desc "fetch -[-dist]", "download a release" method_option :dist, :aliases => "-d", :default => "bin" def fetch(name) archive = KVM::Archive.new(name, options[:dist]) archive.get || puts("Archive #{name} has already been fetched: #{archive.name}") end desc "get -[-dist]", "download and expand a release" method_option :dist, :aliases => "-d", :default => "bin" def get(name) release = KVM::RiceRelease.new(name, options[:dist]) release.get || puts("Release #{name} has already been downloaded: #{release.name}") end desc "list", "list downloaded releases" def list KVM::RiceRelease.list.each { |r| puts r.name } end desc "list-datasets", "lists generated datasets" def list_datasets(project=nil) datasets = KVM::RiceReleaseGeneratedDataset.list for dataset in datasets puts "#{dataset.project} #{dataset.ds_name} #{dataset.db_type}" end end desc "generate-datasets - [-d dataset1,dataset2] [-t oracle|mysql]", "generates DDL for the specified project; if datasets or database type are omitted, all sets/types are generated" method_option :datasets, :aliases => "-d", :type => :array method_option :types, :aliases => "-t", :type => :string def generate_datasets(project) release = KVM::RiceRelease.new(project) release.get dataset_list = (options[:datasets] || release.datasets) # generate sql of each type... if options[:types] db_types = options[:types].split('|') else db_types = KVM::Db::DB_TYPES end for db_type in db_types # for each dataset for ds_name in dataset_list dataset = KVM::RiceReleaseGeneratedDataset.new(release.name, ds_name, db_type) dataset.get end end end desc "install-dataset - dataset [type]", "installs specified dataset" db_method_options def install_dataset(project, ds_name, type=nil) db_config = parse_db_options(options) validate_db_options(db_config) type = resolve_db_type(db_config, type) release = KVM::RiceRelease.new(project) release.get # generate sql if missing KVM::LOG.debug "DATASET: " + ds_name dataset = KVM::RiceReleaseGeneratedDataset.new(release.name, ds_name, type) dataset.get KVM::LOG.debug "Dataset path:" KVM::LOG.debug dataset.path KVM::LOG.debug dataset.exists? KVM::Impex::IMPEX_SOURCE.get KVM::Impex::IMPEX.apply_sql(dataset.path, type, db_config.url, db_config.username, db_config.password) end # ./bin/kvm install-testtables rice-1.0.3.1 oracle --db=alias:oraclexe-system jar:$HOME/.m2/repository/com/oracle/ojdbc14/10.2.0.3.0/ojdbc14-10.2.0.3.0.jar desc "install-testtables - [type]", "installs test tables" db_method_options def install_testtables(project, type=nil) db_config = parse_db_options(options) validate_db_options(db_config) type = resolve_db_type(db_config, type) release = KVM::RiceRelease.new(project) release.get run_sql_file(db_config, release.test_sql_file(type), true) end desc "run-sql file ", "runs a sql file" db_method_options def run_sql(file) db_config = parse_db_options(options) validate_db_options(db_config) resolve_db_type(db_config, nil) run_sql_file(db_config, File.expand_path(file), false) end desc "checkout [path]", "checks out a Kuali project from subversion" def checkout(repo, path="trunk") src = Source.new(repo, path) src.get || puts("#{repo} #{path} already checked out: #{src.path}") end desc "update [path]", "updates a checked out Kuali project" def update(repo, path="trunk") src = Source.new(repo, path) src.get src.update end # ./bin/kvm drop-user rice_test --db=alias:oraclexe-system jar:$HOME/.m2/repository/com/oracle/ojdbc14/10.2.0.3.0/ojdbc14-10.2.0.3.0.jar desc "drop-user ", "drops a database user" db_method_options def drop_user(username) db_config = parse_db_options(options) validate_db_options(db_config) db_type = resolve_db_type(db_config, nil, 'oracle') db = KVM::Db::JdbcAdapter.new(db_config) # prepared statement doesn't work for drop? http://forums.oracle.com/forums/thread.jspa?threadID=504808 db.execute_update(KVM::Db::DB_PLATFORMS[db_type].drop_user(username)) end desc "create-user ", "creates a database user" db_method_options def create_user(username, password) db_config = parse_db_options(options) validate_db_options(db_config) KVM::LOG.debug db_config db_type = resolve_db_type(db_config, nil, 'oracle') db = KVM::Db::JdbcAdapter.new(db_config) # oracle-specific # prepared statement doesn't work for drop? http://forums.oracle.com/forums/thread.jspa?threadID=504808 db.execute_update(KVM::Db::DB_PLATFORMS[db_type].create_user(username, password)) end desc "def ", "creates a database definition alias." db_method_options def def db = parse_db_options(options) raise "alias is required" unless db.alias w = load_wallet dbs = w.data['jdbc'] || {} dbs[name] = { 'type' => db.type, 'url' => db.url, 'username' => db.username, 'password' => db.password } w.data['jdbc'] = dbs w.save puts "Saved #{name} alias:" pp w.data end desc "undef ", "deletes a database definition alias" def undef(name) w = load_wallet dbs = w.data['jdbc'] || {} dbs.delete(name) w.data['jdbc'] = dbs w.save puts "Deleted #{name} alias:" pp w.data end desc "config", "prints the kvm config" def config w = load_wallet pp w.data end protected # uses the db type from either the specified type or the db alias # raises an exception if missing and default is nil def resolve_db_type(db_config, type, default=nil) db_config.db_type = type if type db_config.db_type = default unless db_config.db_type raise "Database type must be specified" unless db_config.db_type db_config.db_type end def run_sql_file(db_config, file, strip_eol = false) db = KVM::Db::JdbcAdapter.new(db_config) statements = KVM::Db::DB_PLATFORMS[db_config.db_type].parse_sql(db, file) # fix strange problem with test create table sql... identifier error unless eols are removed statements.map! { |s| s.gsub(/[\r\n]+/, ' ') } if strip_eol db.execute_update(statements) end # parses database command line options, consulting wallet if alias is specified def parse_db_options(options) # required to merge url, username, password opts into db hash # because thor has a funky hash argument syntax that can't be used # with jdbc urls db = options[:db] || {} db['url'] = options[:url] db['username'] = options[:username] db['password'] = options[:password] db['type'] = options[:type] db['jar'] = options[:jar] raise "No database settings specified" unless db.size > 0 db_alias = db['alias'] if db_alias w = load_wallet db_def = nil db_def = w.data['jdbc'][db_alias] if !w.data['jdbc'].nil? raise "Alias not found: #{db_alias}" unless db_def db = db.merge(db_def) end db_config = OpenStruct.new db_config.alias = db['alias'] db_config.url = db['url'] db_config.username = db['username'] db_config.password = db['password'] db_config.jar = db['jar'] db_config.db_type = db['type'] db_config end def validate_db_options(db) raise("Database url not specified") unless db.url raise("Database username not specified") unless db.username raise("Database password not specified") unless db.password end def load_wallet KVM::Wallet.new(File.expand_path("~/.kvm_data"), File.expand_path("~/.ssh/id_rsa")) end def rice_server_bootstrap_dataset_path(version) "#{RICE_SERVER_DB_REPO_PATH}/rice-release-#{version.gsub('\.', '-')}-br" end def rice_client_bootstrap_dataset_path(version) "#{RICE_CLIENT_DB_REPO_PATH}/rice-release-#{version.gsub('\.', '-')}-br" end end