dbd-adonet-sqlserver 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ = IronRuby DBI - Easing data access for ironruby
2
+
3
+ * http://github.com/casualjim/ironruby-dbi
4
+
5
+ == DESCRIPTION:
6
+
7
+ This project aims to provide adapters based on the .NET System.Data infrastructure.
8
+ It does so to make using existing ruby OR/M solutions easier to integrate.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+
13
+
14
+ == SYNOPSIS:
15
+
16
+
17
+
18
+
19
+ == REQUIREMENTS:
20
+
21
+ * To use the caricature library you need to have uuidtools installed
22
+ (sudo) gem install uuidtools
23
+ (sudo) igem install uuidtools
24
+
25
+ == INSTALL:
26
+
27
+ (sudo) igem install ironruby-dbi
28
+
29
+ == LICENSE:
30
+
31
+ Copyright (c) 2009 IronRuby-DBI team
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ of this software and associated documentation files (the "Software"), to deal
35
+ in the Software without restriction, including without limitation the rights
36
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the Software is
38
+ furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in
41
+ all copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
49
+ THE SOFTWARE.
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'fileutils'
3
+ require 'rake'
4
+ require 'rake/rdoctask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "ironnails"
10
+ gem.summary = %Q{IronNails brings rails like development to IronRuby and WPF}
11
+ gem.description = %Q{IronNails is a framework inspired by the Rails and rucola frameworks. It offers a rails-like way of developing
12
+ applications with IronRuby and Windows Presentation Foundation (WPF).}
13
+ gem.email = "ivan@flanders.co.nz"
14
+ gem.homepage = "http://github.com/casualjim/ironnails"
15
+ gem.authors = ["Ivan Porto Carrero"]
16
+ gem.add_runtime_dependency "thor", ">= 0.11.8"
17
+ gem.add_runtime_dependency "activesupport", ">= 2.3.5"
18
+ gem.add_runtime_dependency "bundler", ">= 0.9.2"
19
+ gem.add_development_dependency "rspec", ">= 0"
20
+ gem.files = FileList["[A-Z]*", "{lib}/**/*"]
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ ##############################################################################
29
+ # OPTIONS
30
+ ##############################################################################
31
+
32
+ PKG_NAME = 'ironruby-dbi'
33
+ PKG_VERSION = "0.2.5"
34
+ AUTHORS = ['Ivan Porto Carrero']
35
+ EMAIL = "ivan@flanders.co.nz"
36
+ HOMEPAGE = "http://casualjim.github.com/ironruby-dbi"
37
+ SUMMARY = "A DBI implementation for .NET based drivers."
38
+
39
+ # These are the common rdoc options that are shared between generation of
40
+ # rdoc files using BOTH 'rake rdoc' and the installation by users of a
41
+ # RubyGem version which builds rdoc's along with its installation. Any
42
+ # rdoc options that are ONLY for developers running 'rake rdoc' should be
43
+ # added in the 'Rake::RDocTask' block below.
44
+ RDOC_OPTIONS = [
45
+ "--quiet",
46
+ "--title", SUMMARY,
47
+ "--main", "README.rdoc"
48
+ ]
49
+
50
+ # Extra files outside of the lib dir that should be included with the rdocs.
51
+ RDOC_FILES = (%w( README.rdoc)).sort
52
+
53
+ # The full file list used for rdocs, tarballs, gems, and for generating the xmpp4r.gemspec.
54
+ PKG_FILES = (%w( Rakefile ironruby-dbi.gemspec ) + RDOC_FILES + Dir["{lib,spec}/**/*"]).sort
55
+
56
+ # RDOC
57
+ #######
58
+ Rake::RDocTask.new do |rd|
59
+
60
+ # which dir should rdoc files be installed in?
61
+ rd.rdoc_dir = 'rdoc'
62
+
63
+ # the full list of files to be included
64
+ rd.rdoc_files.include(RDOC_FILES, "lib/**/*.rb")
65
+
66
+ # the full list of options that are common between gem build
67
+ # and 'rake rdoc' build of docs.
68
+ rd.options = RDOC_OPTIONS
69
+
70
+ # Devs Only : Uncomment to also document private methods in the rdocs
71
+ # Please don't check this change in to the source repo.
72
+ #rd.options << '--all'
73
+
74
+ # Devs Only : Uncomment to generate dot (graphviz) diagrams along with rdocs.
75
+ # This requires that graphiz (dot) be installed as a local binary and on your path.
76
+ # See : http://www.graphviz.org/
77
+ # Please don't check this change in to the source repo as it introduces a binary dependency.
78
+ #rd.options << '--diagram'
79
+ #rd.options << '--fileboxes'
80
+
81
+ end
82
+
83
+
84
+
85
+
86
+ task :test => [:test_dbd]
87
+
88
+ task :default => :test
@@ -0,0 +1,32 @@
1
+ # WARNING : RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!
2
+ # RUN : 'rake gem:update_gemspec'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.authors = ["Ivan Porto Carrero"]
6
+ s.description = "A DBD implementation for .NET access to sqlserver."
7
+ s.email = "ivan@flanders.co.nz"
8
+ s.extra_rdoc_files = ["README.rdoc"]
9
+ s.files = ["README.rdoc",
10
+ "Rakefile",
11
+ "dbd-adonet-sqlserver.gemspec",
12
+ "lib/dbd/mssql.rb",
13
+ "lib/dbd/mssql/database.rb",
14
+ "lib/dbd/mssql/driver.rb",
15
+ "lib/dbd/mssql/statement.rb",
16
+ "lib/dbd/mssql/types.rb"]
17
+ s.has_rdoc = true
18
+ s.homepage = "http://casualjim.github.com/ironruby-dbi"
19
+ s.loaded = false
20
+ s.name = "dbd-adonet-sqlserver"
21
+ s.platform = "ruby"
22
+ s.rdoc_options = ["--quiet", "--title", "A DBD implementation for .NET access to sqlserver.", "--main", "README.rdoc"]
23
+ s.require_paths = ["lib"]
24
+ s.required_ruby_version = ">= 1.8.4"
25
+ s.required_rubygems_version = ">= 0"
26
+ s.rubyforge_project = "dbd-adonet-sqlserver"
27
+ s.rubygems_version = "1.3.5"
28
+ s.add_runtime_dependency "dbd-adonet", "= 0.3.2"
29
+ s.specification_version = 3
30
+ s.summary = "A DBD implementation for .NET access to sqlserver."
31
+ s.version = "0.3.2"
32
+ end
@@ -0,0 +1,185 @@
1
+ require 'rubygems' unless defined? Gem
2
+
3
+ require 'dbd/adonet'
4
+ require 'dbd/adonet/prepared_statement'
5
+
6
+ module DBI
7
+ module DBD
8
+
9
+
10
+
11
+ module MSSQL
12
+
13
+ VERSION = "0.3"
14
+ DESCRIPTION = "ADO.NET Microsoft SQL Server DBI DBD"
15
+
16
+ require File.dirname(__FILE__) + "/mssql/types"
17
+
18
+ # Hash to translate MS SQL Server type names to DBI SQL type constants
19
+ #
20
+ # Only used in #mssql_type_info.
21
+ #
22
+ MSSQL_TO_XOPEN = {
23
+ "TINYINT" => [DBI::SQL_TINYINT, 1, nil],
24
+ "SMALLINT" => [DBI::SQL_SMALLINT, 2, nil],
25
+ "INT" => [DBI::SQL_INTEGER, 4, nil],
26
+ "INTEGER" => [DBI::SQL_INTEGER, 4, nil],
27
+ "BIGINT" => [DBI::SQL_BIGINT, 8, nil],
28
+ "REAL" => [DBI::SQL_REAL, 24, nil],
29
+ "FLOAT" => [DBI::SQL_FLOAT, 12, nil],
30
+ "DECIMAL" => [DBI::SQL_DECIMAL, 18, nil],
31
+ "NUMERIC" => [DBI::SQL_DECIMAL, 18, nil],
32
+ "MONEY" => [DBI::SQL_DECIMAL, 8, 4],
33
+ "SMALLMONEY" => [DBI::SQL_DECIMAL, 4, 4],
34
+ "DATE" => [DBI::SQL_DATE, 10, nil],
35
+ "TIME" => [DBI::SQL_TIME, 8, nil],
36
+ "DATETIME2" => [DBI::SQL_TIMESTAMP, 19, nil],
37
+ "DATETIME" => [DBI::SQL_TIMESTAMP, 19, nil],
38
+ "CHAR" => [DBI::SQL_CHAR, 1, nil],
39
+ "VARCHAR" => [DBI::SQL_VARCHAR, 255, nil],
40
+ "NCHAR" => [DBI::SQL_CHAR, 1, nil],
41
+ "NVARCHAR" => [DBI::SQL_VARCHAR, 255, nil],
42
+ "TEXT" => [DBI::SQL_VARCHAR, 65535, nil],
43
+ "NTEXT" => [DBI::SQL_VARCHAR, 131070, nil],
44
+ "BINARY" => [DBI::SQL_VARBINARY, 65535, nil],
45
+ "VARBINARY" => [DBI::SQL_VARBINARY, 16277215, nil],
46
+ "IMAGE" => [DBI::SQL_LONGVARBINARY, 2147483657, nil],
47
+ "BIT" => [DBI::SQL_BIT, 1, nil],
48
+ "UNIQUEIDENTIFIER" => [DBI::SQL_VARCHAR, 20, nil],
49
+ "XML" => [DBI::SQL_VARCHAR, 65535, nil],
50
+ "TIMESTAMP" => [DBI::SQL_VARCHAR, 18, nil],
51
+ nil => [DBI::SQL_OTHER, nil, nil]
52
+ }
53
+
54
+ MSSQL_TYPEMAP = {
55
+ "TINYINT" => DBI::Type::Integer,
56
+ "SMALLINT" => DBI::Type::Integer,
57
+ "INT" => DBI::Type::Integer,
58
+ "INTEGER" => DBI::Type::Integer,
59
+ "BIGINT" => DBI::Type::Integer,
60
+ "REAL" => DBI::Type::Float,
61
+ "FLOAT" => DBI::Type::Float,
62
+ "DECIMAL" => DBI::DBD::MSSQL::Type::Decimal,
63
+ "NUMERIC" => DBI::DBD::MSSQL::Type::Decimal,
64
+ "MONEY" => DBI::DBD::MSSQL::Type::Decimal,
65
+ "SMALLMONEY" => DBI::DBD::MSSQL::Type::Decimal,
66
+ "DATE" => DBI::DBD::MSSQL::Type::Date,
67
+ "TIME" => DBI::DBD::MSSQL::Type::Timestamp,
68
+ "DATETIME2" => DBI::DBD::MSSQL::Type::Timestamp,
69
+ "DATETIME" => DBI::DBD::MSSQL::Type::Timestamp,
70
+ "CHAR" => DBI::Type::Varchar,
71
+ "VARCHAR" => DBI::Type::Varchar,
72
+ "NCHAR" => DBI::Type::Varchar,
73
+ "NVARCHAR" => DBI::Type::Varchar,
74
+ "TEXT" => DBI::Type::Varchar,
75
+ "NTEXT" => DBI::Type::Varchar,
76
+ "BINARY" => DBI::Type::Varchar,
77
+ "VARBINARY" => DBI::Type::Varchar,
78
+ "IMAGE" => DBI::Type::Varchar,
79
+ "BIT" => DBI::Type::Boolean,
80
+ "UNIQUEIDENTIFIER" => DBI::Type::Varchar,
81
+ "XML" => DBI::Type::Varchar,
82
+ "TIMESTAMP" => DBI::Type::Varchar,
83
+ nil => DBI::DBD::MSSQL::Type::Null,
84
+ System::DBNull => DBI::DBD::MSSQL::Type::Null
85
+ }
86
+
87
+
88
+
89
+ def self.driver_name
90
+ "mssql"
91
+ end
92
+
93
+ DBI::TypeUtil.register_conversion(driver_name) do |obj|
94
+
95
+
96
+ newobj =
97
+ case obj
98
+ when ::DateTime
99
+ "#{obj.strftime("%Y-%m-%d %H:%M:%S")}"
100
+ when ::Time
101
+ "#{obj.strftime("%H:%M:%S")}"
102
+ when ::Date
103
+ "#{obj.strftime("%Y-%m-%d")}"
104
+ when ::NilClass
105
+ System::DBNull.value
106
+ when ::TrueClass
107
+ "1"
108
+ when ::FalseClass
109
+ "0"
110
+ when ::BigDecimal
111
+ obj.to_s("F")
112
+ when ::Numeric, ::String, System::String, ::DBI::Timestamp, ::DBI::Binary
113
+ obj.to_s
114
+ else
115
+ obj
116
+ end
117
+
118
+ [newobj, (newobj.object_id == obj.object_id and not (obj.is_a?(::String) || obj.is_a?(System::String)))]
119
+ end
120
+
121
+
122
+ CLR_TYPES = {
123
+ :TINYINT => "byte",
124
+ :SMALLINT => "short",
125
+ :BIGINT => "long",
126
+ :INT => "int",
127
+ :FLOAT => "double",
128
+ :REAL => "float",
129
+ :SMALLMONEY => "decimal",
130
+ :MONEY => "decimal",
131
+ :NUMERIC => "decimal",
132
+ :DECIMAL => "decimal",
133
+ :BIT => "bool",
134
+ :UNIQUEIDENTIFIER => "Guid",
135
+ :VARCHAR => "string",
136
+ :NVARCHAR => "string",
137
+ :TEXT => "string",
138
+ :NTEXT => "string",
139
+ :CHAR => "char",
140
+ :NCHAR => "char",
141
+ :VARBINARY => "byte[]",
142
+ :IMAGE => "byte[]",
143
+ :DATETIME => "DateTime"
144
+ }
145
+
146
+ SQL_TYPE_NAMES = {
147
+ :BIT => "BIT",
148
+ :TINYINT => "TINYINT",
149
+ :SMALLINT => "SMALLINT",
150
+ :INTEGER => "INTEGER",
151
+ :INT => "INTEGER",
152
+ :BIGINT => "BIGINT",
153
+ :FLOAT => "FLOAT",
154
+ :REAL => "REAL",
155
+ :DOUBLE => "DOUBLE",
156
+ :NUMERIC => "NUMERIC",
157
+ :DECIMAL => "DECIMAL",
158
+ :CHAR => "CHAR",
159
+ :NCHAR => "CHAR",
160
+ :VARCHAR => "VARCHAR",
161
+ :NVARCHAR => "VARCHAR",
162
+ :LONGVARCHAR => "LONG VARCHAR",
163
+ :TEXT => "LONG VARCHAR",
164
+ :NTEXT => "LONG VARCHAR",
165
+ :DATE => "DATE",
166
+ :DATETIME => "DATETIME",
167
+ :TIME => "TIME",
168
+ :TIMESTAMP => "TIMESTAMP",
169
+ :BINARY => "BINARY",
170
+ :VARBINARY => "VARBINARY",
171
+ :LONGVARBINARY => "LONG VARBINARY",
172
+ :IMAGE => "BLOB",
173
+ :BLOB => "BLOB",
174
+ :CLOB => "CLOB",
175
+ :OTHER => "",
176
+ :BOOLEAN => "BOOLEAN",
177
+ :UNIQUEIDENTIFIER => "VARCHAR"
178
+ }
179
+ end
180
+ end
181
+ end
182
+
183
+ require File.dirname(__FILE__) + "/mssql/driver"
184
+ require File.dirname(__FILE__) + "/mssql/database"
185
+ require File.dirname(__FILE__) + "/mssql/statement"
@@ -0,0 +1,142 @@
1
+ module DBI
2
+ module DBD
3
+ module MSSQL
4
+
5
+ class Database < DBI::BaseDatabase
6
+
7
+
8
+ def initialize(dbd_db, attr)
9
+ super
10
+ self['AutoCommit'] = true
11
+ end
12
+
13
+ def disconnect
14
+ unless @trans.nil?
15
+ @trans.rollback unless @attr['AutoCommit']
16
+ @trans = nil
17
+ end
18
+ @handle.close
19
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
20
+ raise DBI::DatabaseError.new(err.message)
21
+ end
22
+
23
+ def prepare(statement)
24
+ Statement.new(statement, self)
25
+ end
26
+
27
+ def ping
28
+ cmd = @handle.create_command
29
+ cmd.command_text = "Select 1"
30
+ begin
31
+ cmd.execute_non_query
32
+ return true
33
+ rescue
34
+ return false
35
+ end
36
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
37
+ raise DBI::DatabaseError.new(err.message)
38
+ end
39
+
40
+ def tables
41
+ @handle.get_schema("Tables").rows.collect { |row| row["TABLE_NAME"].to_s }
42
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
43
+ raise DBI::DatabaseError.new(err.message)
44
+ end
45
+
46
+ def current_transaction
47
+ @trans
48
+ end
49
+
50
+ def has_transaction?
51
+ !@trans.nil?
52
+ end
53
+
54
+ def columns(table)
55
+ sql = "select object_name(c.object_id) as table_name, c.column_id, c.name, type_name(system_type_id) as sql_type,
56
+ max_length, is_nullable, precision, scale, object_definition(c.default_object_id) as default_value,
57
+ convert(bit,(Select COUNT(*) from sys.indexes as i
58
+ inner join sys.index_columns as ic
59
+ on ic.index_id = i.index_id and ic.object_id = i.object_id
60
+ inner join sys.columns as c2 on ic.column_id = c2.column_id and i.object_id = c2.object_id
61
+ WHERE i.is_primary_key = 1 and ic.column_id = c.column_id and i.object_id=c.object_id)) as is_primary_key,
62
+ convert(bit,(Select COUNT(*) from sys.indexes as i
63
+ inner join sys.index_columns as ic
64
+ on ic.index_id = i.index_id and ic.object_id = i.object_id
65
+ inner join sys.columns as c2 on ic.column_id = c2.column_id and i.object_id = c2.object_id
66
+ WHERE i.is_primary_key = 0
67
+ and i.is_unique_constraint = 0 and ic.column_id = c.column_id and i.object_id=c.object_id)) as is_index,
68
+ convert(bit,(Select Count(*) from sys.indexes as i inner join sys.index_columns as ic
69
+ on ic.index_id = i.index_id and ic.object_id = i.object_id
70
+ inner join sys.columns as c2 on ic.column_id = c2.column_id and i.object_id = c2.object_id
71
+ WHERE (i.is_unique_constraint = 1) and ic.column_id = c.column_id and i.object_id=c.object_id)) as is_unique
72
+ from sys.columns as c
73
+ WHERE object_name(c.object_id) = @table_name
74
+ order by table_name"
75
+ stmt = prepare(sql)
76
+ stmt.bind_param("table_name", table.to_s.to_clr_string)
77
+ stmt.execute
78
+ ret = stmt.fetch_all.collect do |row|
79
+ dtn = row[3].upcase
80
+ ColumnInfo.new({
81
+ 'name' => row[2].to_s,
82
+ 'dbi_type' => MSSQL_TYPEMAP[dtn],
83
+ 'mssql_type_name' => dtn,
84
+ 'sql_type' =>MSSQL_TO_XOPEN[dtn][0],
85
+ 'type_name' => DBI::SQL_TYPE_NAMES[MSSQL_TO_XOPEN[dtn][0]],
86
+ 'precision' => row[6].zero? ? row[4] : row[6],
87
+ 'default' => row[8],
88
+ 'scale' => row[7],
89
+ 'nullable' => row[5],
90
+ 'primary' => row[9],
91
+ 'indexed' => row[10],
92
+ 'unique' => row[11]
93
+ })
94
+ end
95
+ stmt.finish
96
+ ret
97
+ end
98
+
99
+ def commit
100
+ unless @attr['AutoCommit']
101
+ @trans.commit if @trans
102
+ @trans = @handle.begin_transaction
103
+ end
104
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
105
+ raise DBI::DatabaseError.new(err.message)
106
+ end
107
+
108
+ def rollback
109
+ unless @attr['AutoCommit']
110
+ @trans.rollback if @trans
111
+ @trans = @handle.begin_transaction
112
+ end
113
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
114
+ raise DBI::DatabaseError.new(err.message)
115
+ end
116
+
117
+ def do(stmt, *bindvars)
118
+ super
119
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
120
+ raise DBI::DatabaseError.new(err.message)
121
+ end
122
+
123
+ def current_connection
124
+ @handle
125
+ end
126
+
127
+ def []=(attr, value)
128
+ if attr == 'AutoCommit' and @attr[attr] != value
129
+ @trans.commit if @trans
130
+ unless value
131
+ @trans = @handle.begin_transaction unless @trans
132
+ else
133
+ @trans = nil
134
+ end
135
+ end
136
+ @attr[attr] = value
137
+ end
138
+
139
+ end # class Database
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,41 @@
1
+ module DBI
2
+ module DBD
3
+ module MSSQL
4
+
5
+ class Driver < DBI::DBD::BaseAdonetDriver
6
+
7
+ PROVIDER_KEY = :mssql
8
+
9
+ def initialize
10
+ super(DBI::IRONRUBY::USES_DBD_VERSION, PROVIDER_KEY)
11
+ end
12
+
13
+ # Connect to the database. DBD Required.
14
+ def connect(db_args, user, auth, attr)
15
+ connection = factory.create_connection
16
+ # db_args = "#{db_args}; MultipleActiveResultSets=true;" unless db_args =~ /MultipleActiveResultSets/i
17
+ connection.connection_string = db_args
18
+ connection.open
19
+ return create_database(connection, attr);
20
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
21
+ raise DBI::DatabaseError.new(err.message)
22
+ end
23
+
24
+ def create_database(connection, attr)
25
+ Database.new(connection, attr)
26
+ end
27
+
28
+ private
29
+
30
+ def data_sources
31
+ conn = factory.create_connection
32
+ conn.open
33
+ ret = conn.get_schema("Databases").rows.collect { |db| db.to_s unless %w(master tempdb model msdb).include? db.to_s }
34
+ conn.close
35
+ ret
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,149 @@
1
+ module DBI
2
+ module DBD
3
+ module MSSQL
4
+
5
+ class Statement < DBI::BaseStatement
6
+
7
+ def initialize(statement, db)
8
+ @connection = db.current_connection;
9
+ @command = @connection.create_command
10
+ @previous_statement = @connection.instance_variable_get :@current_statement
11
+ @connection.instance_variable_set :@current_statement, self
12
+ @statement = DBI::Adonet::PreparedStatement.new(db, statement.to_s).bind
13
+ @command.command_text = @statement.to_clr_string
14
+ @command.transaction = db.current_transaction if db.has_transaction?
15
+ @current_index = 0
16
+ @db = db
17
+ end
18
+
19
+ def bind_param(name, value, attribs={})
20
+ unless name.to_s.empty?
21
+ name = "p#{name}" if name.is_a? Numeric
22
+ parameter = @command.create_parameter
23
+ parm_name = name.to_s.to_clr_string
24
+ parameter.ParameterName = parm_name
25
+ val = value.is_a?(String) ? value.to_clr_string : value #(value || System::DBNull.value)
26
+ parameter.Value = val
27
+ if @command.parameters.contains(parm_name)
28
+ @command.parameters[parm_name] = parameter
29
+ else
30
+ @command.parameters.add parameter
31
+ end
32
+ end
33
+ end
34
+
35
+ def execute
36
+ @previous_statement.finish if @previous_statement
37
+
38
+ @current_index = 0
39
+ @rows = []
40
+ @schema = nil
41
+ finish
42
+ @reader = @command.execute_reader
43
+ schema
44
+ unless SQL.query?(@statement.to_s)
45
+ do_finish true
46
+ end
47
+ @reader.records_affected
48
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
49
+ raise DBI::DatabaseError.new(err.message)
50
+ end
51
+
52
+ def fetch
53
+ if @reader and @reader.is_closed
54
+ if @pending_fetches
55
+ return @pending_fetches.shift
56
+ else
57
+ return nil
58
+ end
59
+ end
60
+ res = nil
61
+ if @reader.read
62
+ res = read_row(@reader)
63
+ end
64
+ puts "result: #{res}, \nclass: #{res.class}" if $quoting_test
65
+
66
+ res
67
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
68
+ raise DBI::DatabaseError.new(err.message)
69
+ end
70
+
71
+ def finish
72
+ do_finish false
73
+ end
74
+
75
+ def do_finish(check_pending_fetches)
76
+ if @reader and not @reader.is_closed
77
+ if check_pending_fetches
78
+ @pending_fetches = []
79
+ while (res = fetch) != nil
80
+ @pending_fetches << res
81
+ end
82
+ else
83
+ @pending_fetches = nil
84
+ end
85
+ @reader.close
86
+ end
87
+
88
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
89
+ raise DBI::DatabaseError.new(err.message)
90
+ end
91
+
92
+ def cancel
93
+ finish
94
+ @command.cancel
95
+ end
96
+
97
+ def schema
98
+ @schema ||= @reader.get_schema_table || System::Data::DataTable.new
99
+ end
100
+
101
+ def column_info
102
+ infos = schema.rows.collect do |row|
103
+ name = row["ColumnName"]
104
+ def_val_col = row.table.columns[name]
105
+ def_val = def_val_col.nil? ? nil : def_val_col.default_value
106
+ dtn = row["DataTypeName"].to_s.upcase
107
+ {
108
+
109
+ 'name' => name.to_s,
110
+ 'dbi_type' => MSSQL_TYPEMAP[dtn],
111
+ 'mssql_type_name' => dtn,
112
+ 'sql_type' =>MSSQL_TO_XOPEN[dtn][0],
113
+ 'type_name' => DBI::SQL_TYPE_NAMES[MSSQL_TO_XOPEN[dtn][0]],
114
+ 'precision' => %w(varchar nvarchar char nchar text ntext).include?(dtn.downcase) ? row["ColumnSize"] : row["NumericPrecision"],
115
+ 'default' => def_val,
116
+ 'scale' => %w(varchar nvarchar char nchar text ntext).include?(dtn.downcase) ? nil : row["NumericScale"] ,
117
+ 'nullable' => row["AllowDBNull"],
118
+ 'primary' => schema.primary_key.select { |pk| pk.column_name == name }.size > 0,
119
+ 'unique' => row["IsUnique"]
120
+ }
121
+ end
122
+ infos
123
+ rescue RuntimeError, System::Data::SqlClient::SqlException => err
124
+ raise DBI::DatabaseError.new(err.message)
125
+ end
126
+
127
+ def rows
128
+ return 0 if @reader.nil?
129
+ res = @reader.records_affected
130
+ res == -1 ? 0 : res
131
+ end
132
+
133
+ private
134
+
135
+ def read_row(record)
136
+ (0...record.visible_field_count).collect do |i|
137
+ res = record.get_value(i)
138
+ if res.is_a?(System::String)
139
+ res.to_s
140
+ else
141
+ res.is_a?(System::DBNull) ? nil : res
142
+ end
143
+ end
144
+ end
145
+
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,70 @@
1
+ module DBI::DBD::MSSQL::Type
2
+
3
+ #
4
+ # Represents a Decimal with real precision (BigDecimal). Falls back to
5
+ # Float.
6
+ #
7
+ class Decimal < DBI::Type::Float
8
+ def self.parse(obj)
9
+ BigDecimal.new(obj.to_s) rescue super
10
+ end
11
+ end
12
+
13
+ #
14
+ # Represents a SQL NULL.
15
+ #
16
+ class Null
17
+ def self.parse(obj)
18
+ return nil if obj.is_a?(System::DBNull) or obj.to_s.match(/^null$/i)
19
+ return obj
20
+ end
21
+ end
22
+
23
+ #
24
+ # Custom handling for TIMESTAMP and DATETIME types in MySQL. See DBI::Type
25
+ # for more information.
26
+ #
27
+ class Timestamp < DBI::Type::Timestamp
28
+
29
+ def self.parse(obj)
30
+ case obj
31
+ when ::DateTime
32
+ return obj
33
+ when ::Date
34
+ return create(obj.year, obj.month, obj.day, 0, 0, 0)
35
+ when ::Time
36
+ return create(obj.year, obj.month, obj.day, obj.hour, obj.min, obj.sec, obj.usec, obj.utc_offset / 86400.0)
37
+ when ::System::DateTime
38
+ return create(obj.year, obj.month, obj.day, obj.hour, obj.minute, obj.second, obj.millisecond)
39
+ else
40
+ obj = super
41
+ return obj unless obj
42
+ return create(*parse_string(obj.to_s)) if obj.respond_to? :to_s
43
+ return create(*parse_string(obj.to_str)) if obj.respond_to? :to_str
44
+ return obj
45
+ end
46
+ end
47
+ end
48
+
49
+ #
50
+ # Custom handling for DATE types in MySQL. See DBI::Type for more
51
+ # information.
52
+ #
53
+ class Date < DBI::Type::Null
54
+ def self.parse(obj)
55
+ obj = super
56
+ return obj unless obj
57
+
58
+ case obj.class
59
+ when ::Date
60
+ return obj
61
+ when ::String
62
+ return ::Date.strptime(obj, "%Y-%m-%d")
63
+ else
64
+ return ::Date.parse(obj.to_s) if obj.respond_to? :to_s
65
+ return ::Date.parse(obj.to_str) if obj.respond_to? :to_str
66
+ return obj
67
+ end
68
+ end
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dbd-adonet-sqlserver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Porto Carrero
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-02 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dbd-adonet
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.3.2
24
+ version:
25
+ description: A DBD implementation for .NET access to sqlserver.
26
+ email: ivan@flanders.co.nz
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - README.rdoc
35
+ - Rakefile
36
+ - dbd-adonet-sqlserver.gemspec
37
+ - lib/dbd/mssql.rb
38
+ - lib/dbd/mssql/database.rb
39
+ - lib/dbd/mssql/driver.rb
40
+ - lib/dbd/mssql/statement.rb
41
+ - lib/dbd/mssql/types.rb
42
+ has_rdoc: true
43
+ homepage: http://casualjim.github.com/ironruby-dbi
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --quiet
49
+ - --title
50
+ - A DBD implementation for .NET access to sqlserver.
51
+ - --main
52
+ - README.rdoc
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.8.4
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: dbd-adonet-sqlserver
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A DBD implementation for .NET access to sqlserver.
74
+ test_files: []
75
+