ruby active_record connection within a class - ruby

My problem is that I want to put my connection and SQL statements in site methods in my class, but when I put it in separate methods and call the methods from elsewhere it won't connect to my MySQL database. My code:
require 'active_record'
class Databaseoperation < ActiveRecord::Base
def initialize
$mysqlinfo = Hash[*File.read('/home/me/properties/mysql.property').split(/=|\n/)]
end
def mysqlConnect
self.establish_connection(:adapter => 'jdbcmysql', :database => 'mydb' , :host => 'localhost', :username => 'root', :password => 'root' )
end
def getSqlServer
$record = MysqlConnection.connection.select_all('SELECT * from Installation')
end
end
dbp = Databaseoperation.new
dbp.mysqlConnect
Error message:
ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished
retrieve_connection at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:546
retrieve_connection at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/connection_handling.rb:79
connection at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/connection_handling.rb:53
columns at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/model_schema.rb:208
column_names at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/model_schema.rb:247
define_attribute_methods at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/attribute_methods.rb:29
synchronize at org/jruby/ext/thread/Mutex.java:149
define_attribute_methods at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/attribute_methods.rb:26
method_missing at /home/me/.rvm/gems/jruby-1.7.4/gems/activerecord-4.0.0/lib/active_record/attribute_methods.rb:123
mysqlConnect at ./databaseoperation.rb:12
(root) at ./databaseoperation.rb:23
If I don't put my statements inside methods in my class it connects to the database. But I really would like to be able to have connections and sql statements separated in methods for my class. How can I do this? Note that I'm using jruby-1.7.4.

Related

Can't connect to local MySQL server through socket. I want to connect to REMOTE db

This is my code.
I want to connect to remote database
require 'bundler/setup'
#require "mysql"
#require 'mysql2'
#require "active_record"
Bundler.require
#db_host = ENV["HOST"]
#db_user = ENV["USER"]
#db_pass = ENV['PASSWORD']
#db_name = "db_name"
require "active_record"
ActiveRecord::Base.establish_connection(
:adapter => 'mysql2',
:database => #db_name,
:username => #db_user,
:password => #db_pass,
:host => #db_host)
class ConversionRate < ActiveRecord::Base
end
class ConversionRateMonthly < ActiveRecord::Base
self.table_name = "conversion_rates_monthly"
end
class KdpReport < ActiveRecord::Base
end
class SalesCalculator
def run
p KdpReport.count
end
end
calculator = SalesCalculator.new
calculator.run
But I get this error:
/home/jonsdirewolf/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/mysql2-0.4.9/lib/mysql2/client.rb:89:in `connect': Can't connect to local MySQL server through socket
'/var/run/mysqld/mysqld.sock' (2) (Mysql2::Error)
It is strange but yesterday my code worked. what may be wrong? I want to connect to remote db, not local. And btw I use ruby without rails.
So, the problem is in empty environment var ENV["HOST"].
When host, passed to ActiveRecord is nil or equl to string localhost - AR will try to connect to db using socket.

how do I read from a Database in ruby sinatra using active record

I want to read entrys from a Database using active_record and keep getting diffrent Errors like: Name error and can't find the database or it can't execute the query.
so my question here is how do i read from a database or execute SQL-queries and for example write the result into a variable?
require 'rubygems'
require 'sinatra'
require 'active_record'
require 'sqlite3'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "test.db"
)
class Article < ActiveRecord::Base
end
#ActiveRecord::Migration.create_table :users do |t|
# t.string :name
#end
class App < Sinatra::Application
end
get '/' do
output = users.select(:all)
f = File.open('name','a'); f.write(output); f.close
#puts User.first
To read the data from the users table, you'd simply do:
class User < ActiveRecord::Base
end
get '/' do
#users = User.all
puts "Grabbed #{#users.size} user(s) from database"
end

Activerecord returning all results as a hash

I have the following connecting to a db called dbblah and table1(names changed)
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "192.168.1.10",
:database => "automation",
:username => "root",
:password => "password"
)
ActiveRecord::Base.pluralize_table_names = false
class Table1 < ActiveRecord::Base
end
db = Table1.find_by(db: 'dbname')
puts db
But when I run it, I am getting the results as a hash it looks like:
[root#localhost server]# ruby blah.rb
#<Table1:0x000000019796a8>
This is just the output of to_s method called on a new object - it is definitively not a hash. By default when calling puts method with a non-string, to_s method is called on that object to display a string. For ActiveRecord models to_s method results in exactely what you got.
Try calling p db to display result of method inspect called on that object, which will give you more insight in its internal structure.

EM::Synchrony.defer with fiber aware database call causes FiberError exception

I'm trying to use EM-Synchrony for concurrency in an application and have come across an issue with my use of deferred code and Fibers.
Any calls to the database within either EM.defer or EM::Synchrony.defer results in the application crashing with the error can't yield from root fiber
Below is a very trimmed down runnable example of what I'm trying to accomplish. The first print works and displays [:first, 1] but the second is where I crash with the error mentioned above.
require 'mysql2'
require 'em-synchrony/activerecord'
ActiveRecord::Base.establish_connection(
:adapter => 'em_mysql2',
:username => 'user',
:password => 'pass',
:host => 'localhost',
:database => 'app_dev',
:pool => 60
)
class User < ActiveRecord::Base; end
EM.synchrony do
p [:first, User.all.count]
EM::Synchrony.defer do
p [:second, User.all.count]
end
end
My first thought was perhaps the Fiber.current and Fiber.yield within EM::Synchrony.defer meant I could fix the problem with an extra Fiber.new call
EM::Synchrony.defer do
Fiber.new do
p [:second, User.all.count]
end.resume
end
This fails to run as well but this time I get the error fiber called across threads.

How to Handle ActiveRecord Migrations in a Distributed Gem?

I am trying to write an app as a gem using ActiveRecord without Rails.
My problem is how to migrate a database already deployed by a user who will not have rake, etc. I have just distributed a schema.rb file and created the db from that. But now I want to allow users to update to a new gem and migrate their db.
I've looked at ActiveRecord::Migrator, but can't figure out how to use it.
For example, how would I tell ActiveRecord::Migrator to run all migrations up from whatever is the current_migration?
Anyone have any suggestions for how to go about this or a good reference?
After going at this fresh this morning I came up with the following which is working well:
module Byr
module Db
class << self
attr_accessor :config
attr_accessor :adapter
attr_accessor :db_name
end
def self.create_sqlite(config)
require 'sqlite3'
config = config.merge('database' => File.join(Byr.db_dir, config['database']))
ActiveRecord::Base.establish_connection(config)
end
def self.create_pg(config)
require 'pg'
# Connect to the postgres db to create the db
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres',
'schema_search_path' => 'public'))
begin
result = ActiveRecord::Base.connection.create_database(config['database'])
rescue PG::Error, ActiveRecord::StatementInvalid => e
unless e.message =~ /already exists/
raise
end
end
true
end
def self.mysql_creation_options(config)
#charset = ENV['CHARSET'] || 'utf8'
#collation = ENV['COLLATION'] || 'utf8_unicode_ci'
{:charset => (config['charset'] || #charset), :collation => (config['collation'] || #collation)}
end
def self.create_mysql(config)
require 'mysql2'
error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
begin
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.establish_connection(config)
rescue error_class => sqlerr
access_denied_error = 1045
if sqlerr.errno == access_denied_error
print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
root_password = $stdin.gets.strip
grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
"TO '#{config['username']}'#'localhost' " \
"IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
ActiveRecord::Base.establish_connection(config.merge(
'database' => nil, 'username' => 'root', 'password' => root_password))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.connection.execute grant_statement
ActiveRecord::Base.establish_connection(config)
else
Byr.warn sqlerr.error
Byr.warn "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || #charset}, collation: #{config['collation'] || #collation}"
Byr.warn "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
end
rescue ActiveRecord::StatementInvalid => e
ActiveRecord::Base.establish_connection(config)
end
end
def self.migrate
sys_migration_dir = File.join(Byr.install_dir, "db/migrate")
ActiveRecord::Migration.verbose = true
ActiveRecord::Migrator.migrate(sys_migration_dir)
end
def self.connected?
ActiveRecord::Base.connected? and
ActiveRecord::Base.connection_config[:adapter] == adapter
end
def self.disconnect
ActiveRecord::Base.connection_pool.disconnect!
end
# Really only for testing
def self.drop_db
ActiveRecord::Base.connection.drop_database(Byr.db_config)
end
end
end
Then, to initialize the db via the migrations:
module Byr
class << self
attr_accessor :install_dir
attr_accessor :db_dir
attr_accessor :config_dir
attr_accessor :config_file
attr_accessor :config
attr_accessor :db_config
attr_accessor :adapter
attr_accessor :database
def self.create_db
case db_config['adapter']
when /postgresql/
Byr::Db.create_pg(db_config)
when /sqlite/
Byr::Db.create_sqlite(db_config)
when /mysql/
Byr::Db.create_mysql(db_config)
else
raise ByrError "Your config.yml file specifies an unknown database adapter \'#{config['adapter']}\'"
end
end
def self.connect_db(reconnect = false)
unless reconnect
return true if Byr.connected?
end
ActiveRecord::Base.establish_connection(db_config)
end
def self.migrate
Byr::Db.migrate
end
def self.init(connect = true, adapter = nil)
adapter = canonicalize_adapter(adapter) if adapter
setup_db_config
if connect
create_db and connect_db and migrate
end
end
end
Some irrelevant parts of the code are omitted, but I hope this helps
someone else.
Much of the hard stuff comes from the rake tasks in rails.

Resources