dbd-adonet-sqlserver 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+