其实很简单,我把ADO.rb给改了,加了编码转换,这样rails端使用起来就不需要做太特殊修改了。
#
# DBD::ADO
#
# Copyright (c) 2001, 2002 Michael Neumann <neumann@s-direktnet.de>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# $Id$
#
require "win32ole"
require "iconv"
module DBI
module DBD
module ADO
VERSION = "0.1"
USED_DBD_VERSION = "0.1"
class Driver < DBI::BaseDriver
def initialize
super(USED_DBD_VERSION)
end
def connect(dbname, user, auth, attr)
# connect to database
handle = WIN32OLE.new('ADODB.Connection')
handle.Open(dbname)
handle.BeginTrans() # start new Transaction
return Database.new(handle, attr)
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
end
class Database < DBI::BaseDatabase
def disconnect
@handle.RollbackTrans()
@handle.Close()
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def prepare(statement)
# TODO: create Command instead?
Statement.new(@handle, statement, self)
end
def commit
# TODO: raise error if AutoCommit on => better in DBI?
@handle.CommitTrans()
@handle.BeginTrans()
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def rollback
# TODO: raise error if AutoCommit on => better in DBI?
@handle.RollbackTrans()
@handle.BeginTrans()
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def []=(attr, value)
if attr == 'AutoCommit' then
# TODO: commit current transaction?
@attr[attr] = value
else
super
end
end
end # class Database
class Statement < DBI::BaseStatement
include SQL::BasicBind
include SQL::BasicQuote
def initialize(handle, statement, db)
@iconv_in = Iconv.new('gb18030','utf-8')
@iconv_out = Iconv.new('utf-8','gb18030')
@handle = handle
@statement = @iconv_in.iconv(statement)
@params = []
@db = db
end
def bind_param(param, value, attribs)
raise InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
@params[param-1] = value
end
def execute
# TODO: use Command and Parameter
# TODO: substitute all ? by the parametes
#sql = bind(self, @statement, @params)
@res_handle = @handle.Execute(@statement)
# TODO: SELECT and AutoCommit finishes the result-set
# what to do?
if @db['AutoCommit'] == true and not SQL.query?(@statement) then
@db.commit
end
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def finish
# if DCL, DDL or INSERT UPDATE and DELETE, this gives an Error
# because no Result-Set is available
if @res_handle.Fields.Count() != 0 then
@res_handle.Close()
end
rescue RuntimeError => err
raise DBI::DatabaseError.new(err.message)
end
def fetch
retval = fetch_currentrow
@res_handle.MoveNext() unless retval.nil?
retval
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def fetch_scroll(direction, offset)
case direction
when DBI::SQL_FETCH_NEXT
return fetch
when DBI::SQL_FETCH_PRIOR
# TODO: check if already the first?
#return nil if @res_handle.AbsolutePosition()
@res_handle.MovePrevious()
return fetch_currentrow
when DBI::SQL_FETCH_FIRST
@res_handle.MoveFirst()
return fetch_currentrow
when DBI::SQL_FETCH_LAST
@res_handle.MoveLast()
return fetch_currentrow
when DBI::SQL_FETCH_RELATIVE
@res_handle.Move(offset)
return fetch_currentrow
when DBI::SQL_FETCH_ABSOLUTE
ap = @res_handle.AbsolutePositon()
@res_handle.Move(offset-ap)
return fetch_currentrow
else
raise DBI::InterfaceError
end
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def column_info
num_cols = @res_handle.Fields().Count()
retval = Array.new(num_cols)
for i in 0...num_cols do
retval[i] = {'name' => @iconv_out.iconv(@res_handle.Fields(i).Name())}
end
retval
rescue RuntimeError => err
raise DBI::DatabaseError.new(@iconv_out.iconv(err.message))
end
def rows
# TODO: how to get the RPC in ADO?
nil
end
private
def fetch_currentrow
return nil if @res_handle.EOF() or @res_handle.BOF()
# TODO: don't create new Array each time
num_cols = @res_handle.Fields().Count()
retval = Array.new(num_cols)
for i in 0...num_cols do
if @res_handle.Fields(i).Value().is_a? String
retval[i] = @iconv_out.iconv(@res_handle.Fields(i).Value())
else
retval[i] = @res_handle.Fields(i).Value()
end
end
retval
end
end
end # module ADO
end # module DBD
end # module DBI
用上面的文件内容替换掉原来的ADO.rb。如果你没装过ADO.rb,直接把内容另存为ruby\lib\ruby\site_ruby\1.8\DBD\ADO\ADO.rb就可以了。
分享到:
相关推荐
NULL 博文链接:https://xieye.iteye.com/blog/481576
SQL Server - Rails ActiveRecord的SQL Server适配器
简介 Ruby On Rails 框架自它提出之日...Rails 是一个真正彻底的 MVC(Model-View-Controller) 框架,Rails 清楚地将你的模型的代码与你的控制器的应用逻辑从 View 代码中分离出来。Rails 开发人员很少或者可能从未遇到
NULL 博文链接:https://hlee.iteye.com/blog/587000
Ruby on Rails中文指南
shoppe-example, 在 Rails 中使用Shoppe平台的示例存储实现 这是一个 Rails 应用程序,它使用 Shoppe 构建。 它具有一个可以爱的设计,以充分演示Shoppe平台提供的功能以及它在 Rails 应用程序中的。 正在启动要开始...
迁移中的所有简化的Rails类型都将与匹配SQL Server国家(unicode)数据类型相对应。 始终检查initialize_native_database_types 以获取更新的列表。 以下类型( date , datetime2 , datetimeoffset ,
今天想用ruby on rails做一个小项目,需要用到mysql数据库,项目中的数据已经有了,只不过是保存在Sql Server中,用rails倒是可以操作Sql Server,但是总感觉不怎么搭配,想转换后使用,网上翻了下,转换的办法有很多,通过...
使用Aptana+Rails开发Rails Web应用 有Aptana的安装配置等等,中文
这个是本人做的一个网上书城struts+jsp+SqlServer项目,有需要可以看看
rails-assets, 在 Rails 中,资产管理的解决 Rails 资产 Bundler 到 Bower 代理本自述文件涉及项目的开发方面。 访问站点了解如何在你的应用程序中使用 Rails 资产。 插件开发设置git clone git@github.com:tenex/r
目标 Rails 4.1.x 和 activerecord-sqlserver-adapter 4.1.0。 用法 添加到 Gemfile: gem 'tiny_tds' gem 'activerecord-sqlserver-adapter-mirroring' 将镜像部分添加到 database.yml: development: ...
博文链接:https://ziyoujiedao.iteye.com/blog/148307
一个用Ruby on Rails搭建的图片分享的网站项目.完整源代码
Ruby On Rails中文教材(PDF)
rails, Ruby on Rails 欢迎使用 RailsRails 是一个web应用程序框架,它包括根据 Model-View-Controller ( MVC ) Pattern 创建数据库备份的web应用程序所需的所有内容。理解 MVC Pattern 是理解 Rai
NULL 博文链接:https://hlee.iteye.com/blog/345775
rails指南 中文版
敏捷Rails中文教程 敏捷Rails中文教程 敏捷Rails中文教程