This is an odd one. I have some ruby code on my machine which uses the tiny_tds version:
0.6.0.rc1
and everything works fine. When a co-worker attempt to run the same code he gets the following error:
TinyTds::Error: Adaptive Server connection failed
We are connecting without providing username or password as it's not needed on my machine. Any ideas? could this be a rights thing on the sql database?
Thanks in advance
It should be noted on the machine with issues we have SQL 2008 R2 and SQL Express installed. We can connect to SQL express but not SQL 2008 R2
Here's the code we are using
def self.GetTestMprsFromDB(dataServer,database,query)
mprids = Array.new
client = TinyTds::Client.new(:dataserver => dataServer, :database => database, :timeout => 1000)
When stepping into tiny_tds on initialize
def initialize(opts={})
if opts[:password] && opts[:password].to_s.strip != ''
opts[:password] = opts[:password].to_s
warn 'FreeTDS may have issues with passwords longer than 30 characters!' if opts[:password].length > 30
end
raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
#query_options = ##default_query_options.dup
opts[:appname] ||= 'TinyTds'
opts[:tds_version] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['71']
opts[:login_timeout] ||= 60
opts[:timeout] ||= 5
opts[:encoding] = (opts[:encoding].nil? || opts[:encoding].downcase == 'utf8') ? 'UTF-8' : opts[:encoding].upcase
opts[:port] ||= 1433
opts[:dataserver] = "#{opts[:host]}:#{opts[:port]}" if opts[:dataserver].to_s.empty?
connect(opts)
end
At end it throws the error
Related
Sequel Model is not mapping all columns by default.
I'm using:
Sequel version 4.24.0
Ruby version 1.9.3p194
Windows Server 2008 Enterprise
SQLServer 2008 R2 Enterprise
Below is a brief script that shows the problem:
require "sequel"
DB = Sequel.ado(:conn_string=>CONNECTION_STRING)
print "Loading LnProfile... "
class LnProfile < Sequel::Model(:lnprofile)
# attr_accessor :crawl_start_time
end
puts "Done!"
id = "808d8421-6c05-471e-addc-6165de044ad3"
# crawl_start_time field shouldn't be empty
p1 = LnProfile.where(:id=>id).first
puts ".id:#{p1.id.to_s}:." # => .id:808d8421-6c05-471e-addc-6165de044ad3:.
puts ".crawl_start_time:#{p1.crawl_start_time.to_s}:." # => .crawl_start_time::.
# same record, different data
p2 = LnProfile.select_all.select_append(:crawl_start_time).where(:id=>id).first
puts ".id:#{p2.id.to_s}:." # => .id:808d8421-6c05-471e-addc-6165de044ad3:.
puts ".crawl_start_time:#{p2.crawl_start_time.to_s}:." # => .crawl_start_time:2016-01-10 12:02:29 -0300:.
Below is the output of the script above:
Loading LnProfile... Done!
.id:{808D8421-6C05-471E-ADDC-6165DE044AD3}:.
.crawl_start_time::.
.id:{808D8421-6C05-471E-ADDC-6165DE044AD3}:.
.crawl_start_time:2016-01-10 12:02:29 -0300:.
Please advice. This issue is dirtying the database when the code loads an object and saves it again few lines above.
Thanks in advance.
Try using the tinytds adapter, it is much more robust than the ado adapter.
So, I am trying to get redmine_backlogs to work with SQL server. [We are using SQL Server rather than SQLite, to scale better]
I am NOT a Ruby programmer, but I really want this plugin for my team, as we actively use Redmine for several projects.
After reading through some Ruby tutorials, I've managed to get make some modifications and get the plugin installed and migrated correctly [it appears].
On the plugin settings screen [in administration] in Redmine, it shows the migration wasn't successful.
Even though all the list items are green, and the migrations appeared to work.
Any ideas?
The changes I made were to bypass suspected issues with the way Active records handles direct SQL queries.
Here are the changes I've made -
ERROR #1 –
C:\Projects\Redmine\redmine-2.3.2>rake redmine:plugins:migrate
Migrating redmine_backlogs (Redmine Backlogs)...
== AddStoryPositions: migrating ==============================================
-- execute("select max(position) from issues")
-> 0.0020s
-> -1 rows
rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `each' for -1:FixnumC:/Projects/Redmine/redmine-2.3.2/plugins/redmine_backlogs/db/migrate/026_add_story_positions.rb:10:in `up'
FIX #1 –
Direct queries are not working correctly with the sqladapter [TinyTds + Active Record]
026_add_story_positions.rb
class AddStoryPositions < ActiveRecord::Migration
def self.up
# Rails doesn't support temp tables, mysql doesn't support update
# from same-table subselect
unless RbStory.trackers.size == 0
max = 0
dbconfig = YAML.load_file(File.join(File.dirname(__FILE__), '../../../../config/database.yml'))#[Rails.env]['username']
if dbconfig[Rails.env]['adapter'] == 'sqlserver' then
database = dbconfig[Rails.env]['database']
dataserver = dbconfig[Rails.env]['dataserver']
mode = dbconfig[Rails.env]['mode']
port = dbconfig[Rails.env]['port']
username = dbconfig[Rails.env]['username']
password = dbconfig[Rails.env]['password']
client = TinyTds::Client.new(
:database => database,
:dataserver => dataserver,
:mode => mode,
:port => port,
:username => username,
:password => password)
client.execute("select max(position) from issues").each{|row| max = row[0]}
client.execute "update issues
set position = #{max} + id
where position is null and tracker_id in (#{RbStory.trackers(:type=>:string)})"
else
execute("select max(position) from issues").each{|row| max = row[0]}
execute "update issues
set position = #{max} + id
where position is null and tracker_id in (#{RbStory.trackers(:type=>:string)})"
end
end
end
def self.down
puts "Reverting irreversible migration"
end
end
ERROR #2
rake aborted!
An error has occurred, this and all later migrations canceled:
TinyTds::Error: ALTER TABLE ALTER COLUMN position failed because one or more objects access this column.: ALTER TABLE [issues] ALTER COLUMN [position]
integer NOT NULLC:/Projects/Redmine/redmine-2.3.2/plugins/redmine_backlogs/db/migrate/033_unique_positions.rb:30:in `up'
FIX #2
033_unique_positions.rb
#SQLServer cannot change the type of an indexes column, so it must be dropped first
remove_index :issues, :position
change_column :issues, :position, :integer, :null => false
add_index :issues, :position
ERROR #3
rake aborted!
undefined method each' for -1:Fixnum
C:/Projects/Redmine/redmine-2.3.2/plugins/redmine_backlogs/lib/backlogs_setup.rb:155:inmigrated?'
FIX #3
def migrated?
available = Dir[File.join(File.dirname(__FILE__), '../db/migrate/*.rb')].collect{|m| Integer(File.basename(m).split('_')[0].gsub(/^0+/, ''))}.sort
return true if available.size == 0
available = available[-1]
ran = []
dbconfig = YAML.load_file(File.join(File.dirname(__FILE__), '../../../config/database.yml'))#[Rails.env]['username']
if dbconfig[Rails.env]['adapter'] == 'sqlserver' then
database = dbconfig[Rails.env]['database']
dataserver = dbconfig[Rails.env]['dataserver']
mode = dbconfig[Rails.env]['mode']
port = dbconfig[Rails.env]['port']
username = dbconfig[Rails.env]['username']
password = dbconfig[Rails.env]['password']
client = TinyTds::Client.new(
:database => database,
:dataserver => dataserver,
:mode => mode,
:port => port,
:username => username,
:password => password)
client.execute("select version from schema_migrations where version like '%-redmine_backlogs'").each{|m|
ran << Integer((m.is_a?(Hash) ? m.values : m)[0].split('-')[0])
}
else
Setting.connection.execute("select version from schema_migrations where version like '%-redmine_backlogs'").each{|m|
ran << Integer((m.is_a?(Hash) ? m.values : m)[0].split('-')[0])
}
end
return false if ran.size == 0
ran = ran.sort[-1]
return ran >= available
end
module_function :migrated?
I was using the wrong where clause -
This is the correct one, I must have overwritten when debugging.
'%-redmine_backlogs'
The above code works.
I could not answer my own question before, but now I can.
The above code was tested and works. I have been running backlogs on Windows with MS SQL successfully since.
I'm using Ruby cucumber to automate my application. I'm using DSN ODBC driver and "dbi" to connect to my sql server 2012 DB. It is connected successfully and I can get the records. But when I'm trying to get unicode (utf-8) data from a table in ruby scripts, I get garbage characters (???????).
Please help me get unicode characters from DB.
Below is the code what I have used to connect and retrieve data from DB.
# encoding: UTF-8
require 'rubygems'
require 'DBI'
def run_select_query_verifyText(query,verifyString)
connection = nil
status = false
begin
#puts "Connecting to DataBase"
connection = DBI.connect('DBI:ODBC:ODBCDriver','test','xxxxx')
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
return false
end
#execute sql query
dataset = connection.execute(query)#.fetch_all
dataset.each do |row|
row.each do |data|
puts "cell data is #{data}"
if data == verifyString then
status = true
break
end
end
if status then
break
end
end
connection.disconnect
return status
end
I had similar issue, which is fixed with following line in env.rb file
ENV['CUCUMBER_OUTPUT_ENCODING'] = 'UFT-8'
I'm having issues getting Sequel to connect to a MS SQL Database.
I have installed the following:
UnixODBC
FreeTDS
I have configured both software packages, and the following commands allow me to connect to my database without a problem:
isql
tsql
osql
However, when I try it from Ruby code using the Sequel.odbc command, I receive the following error:
ODBC::Error: IM003 (0) [iODBC][Driver Manager]Specified driver could not be loaded.
This is as far as I can get. I used to receive another error first, but managed to solve that by redoing the configuration part. Guess I missed something there.
EDIT
This is the code for my base talker class. It basically loads a YAML file like rails does, holding the database settings and establishes a connection to the database.
This seems to be working, trying it manually returns me a DB object from sequel:
module Talkers
require 'yaml'
require 'sequel'
class BaseTalker
# This function will load the desired settings as a hash from the database.yml file
# in the config folder. The data will be returned as a hash following the standard
# YAML structure.
def self.load_config(name)
cfg = YAML::load(File.open(File.join(ENV['API_ROOT'], 'config', 'database.yml')))
cfg.key?(name) ? cfg[name] : nil
end
# This function will establish a connection with the Florensia User database and return
# the Sequel database object, so that queries can be executed against the database.
def self.connect_to_user_db
settings = self.load_config("florensia_user_#{ENV['RACK_ENV']}")
Sequel.odbc settings['dsn'], :db_type => settings['adapter'], :user => settings['user'], :password => settings['password']
end
end
end
The class below inherits from the talker and performs certain actions for a User. It contains the DB logic specific to the game. When I call this logic, I receive the errors:
module Talkers
require 'yaml'
require 'sequel'
class LoginDbTalker < BaseTalker
#
# Bans the specified User from the game. The function requires the following information
# to be supplied in order for the ban to be properly set:
# - id : The identifier of the account.
# - gm_name : The name of the GM setting the ban.
# - punish_code : The punishment code being applied on the account.
# - days : The duration of the ban in days, starting from today.
#
# The function will return true if the ban has been properly set; otherwise the function
# will return false.
def self.ban_user(options = {})
return false if options.empty?
db = self.connect_to_user_db
ds = db[:tbl_User].filter(:id => options[:id])
ps = ds.prepare(:update, :apply_ban)
ps.call(
:punishcode => options[:punish_code],
:punishstory => "Banned by #{options[:gm_name]}",
:punishdate => Date.today,
:punishfreedate => (options[:days].to_i == -1) ? (Date.today + (30 * 265)) : (Date.today + options[:days].to_i))
true
rescue Exception => e
puts "Exception caught in ban_user: #{e.to_s}"
puts "Provided variables: id=#{options[:id]}, gm_name=#{options[:gm_name]}, punish_code=#{options[:punish_code]}, days=#{options[:days]}"
false
end
#
# Unbans the specified User from the game. The function requires the following information
# to be supplied in order for the ban to be properly lifted:
# - id : The identifier of the account.
# - gm_name : The name of the GM removing the ban.
#
# The function will return true if the ban has been properly lifted; otherwise the function
# will return false.
def self.unban_user(options = {})
db = self.connect_to_user_db
ds = db[:tbl_User].filter(:id => options[:id])
ps = ds.prepare(:update, :lift_ban)
ps.call(
:punishcode => '0',
:punishstory => "Ban removed by #{options[:gm_name]}",
:punishdate => Date.today,
:punishfreedate => Date.today
)
true
rescue Exception => e
puts "Exception caught in unban_user: #{e.to_s}"
puts "Provided variables: id=#{options[:id]}, gm_name=#{options[:gm_name]}"
false
end
#
# Kicks the specified User from the game, regardless on the server or character he currently is on.
# This requires a direct connection to the game servers so a specialized command can be sent that
# instruct the server to close the connection with the offending player.
# The function returns true if the kick succeeded; otherwise false.
def self.kick_player(id)
false
end
end
end
Calling any of the ban/unban functions results in the error message.
EDIT2
I've added the folder /Library/ODBC and linked all config files to there for iODBC. This removes the error I had before and now brings me this error:
ODBC::Error: 01000 (20002) [FreeTDS][SQL Server]Adaptive Server connection failed
So it seems I made some progress again
I recommend you use the tinytds adapter instead of the odbc adapter if you are connecting to Microsoft SQL Server from OS X. I know there are people who have got Sequel/ODBC running on non-Windows boxes, but I only have experience with Sequel/ODBC on Windows.
I need to create a script in ruby to get all the database objects (tables,views,sps, functions, etc) and be able to create files for each of the db objects.
I would like to be able to implement this solution in ruby and use some sort of Win32 class may be?.
I am using SQL Server 2008 R2. Not ruby on rails of course.
# == Name
# SQL Server Library
# == Author
# Maverick
# == Synopsis
# ADO SQL Server Library
# == Notes:
# Modify the following global variables in order to set up an execution environment
# sql_str: This is the SQL CMD command option and arguments -> Change the -U and -P arguments for -E to enable integrated security
# http://rubyonwindows.blogspot.com/2007/03/ruby-ado-and-sqlserver.html
Thread.abort_on_exception = true
require 'win32ole'
require 'win32api'
CoInitialize = Win32API.new('ole32', 'CoInitialize', 'P', 'L')
# This class manages database connection and queries
class SqlServer
attr_accessor :connection, :data, :fields
def initialize
#connection = nil
#data = nil
#cmd_time_out = 900
end
#opens a database connection using integrated security
def open(server,database)
connection_string = "Provider=SQLOLEDB.1;"
connection_string << "Persist Security Info=False;"
connection_string << "Integrated Security=SSPI;"
connection_string << "Initial Catalog=#{database};"
connection_string << "Data Source=#{server};"
connection_string << "Network Library=dbmssocn"
CoInitialize.call( 0 )
if server.eql?(nil) or database.eql?(nil) or server.eql?('') or database.eql?('') then
raise Exception, "Application Error: Server or Database parameters are missing"
end
begin
#connection = WIN32OLE.new('ADODB.Connection')
#connection.ConnectionString = connection_string
#connection.open
rescue Exception => e
#connection.Errors.Count.times { |x|
show_ado_error(#connection.Errors)
}
raise Exception, "Application Error: #{e.message} \n Can't open a connection with the server. Verify user credentials"
end
end
def get_connection
return #connection
end
#executes a query without returning any rows
def execute_non_query(query)
begin
command = WIN32OLE.new('ADODB.Command')
command.CommandType = 1
command.ActiveConnection = #connection
command.CommandText = query
command.CommandTimeOut = #cmd_time_out
result = command.Execute
if #connection.Errors.Count > 1 then
raise Exception,"ADODB Connection contains errors"
end
rescue Exception => e
show_ado_error(#connection.Errors)
raise Exception, "Application Error: #{e.message} \n Can't execute query. Verify sql syntax"
end
return result
end
#prints ado db errors using ado connection error property
def show_ado_error(obj)
obj.Count.times { |x|
puts "#{x}. ADODB Error Number: " + #connection.Errors(x).Number.to_s
puts "#{x}. ADODB Generated By: " + #connection.Errors(x).Source
puts "#{x}. ADODB SQL State: " + #connection.Errors(x).SQLState
puts "#{x}. ADODB Native Error: " + #connection.Errors(x).NativeError.to_s
puts "#{x}. ADODB Description: " + #connection.Errors(x).Description
}
end
#executes a query returning an array of rows
def execute_query(sql_query)
# Create an instance of an ADO Record set
begin
record_set = WIN32OLE.new('ADODB.Recordset')
# Open the record set, using an SQL statement and the
# existing ADO connection
record_set.open(sql_query, #connection)
# Create and populate an array of field names
#fields = []
record_set.fields.each do |field|
#fields << field.Name
end
begin
# Move to the first record/row, if any exist
record_set.movefirst
# Grab all records
#data = record_set.getrows
rescue
#data = []
end
record_set.close
# An ADO Recordset's GetRows method returns an array
# of columns, so we'll use the transpose method to
# convert it to an array of rows
#data = #data.transpose
rescue
raise Exception, "Application Error: Can't execute query. Verify SQL Query syntax"
end
end
def close
#connection.Close
end
end