ydbi 0.5.0

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.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/ChangeLog +3699 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/Rakefile +8 -0
  7. data/TODO +44 -0
  8. data/bench/bench.rb +79 -0
  9. data/bin/dbi +518 -0
  10. data/bin/test_broken_dbi +37 -0
  11. data/build/Rakefile.dbi.rb +60 -0
  12. data/build/rake_task_lib.rb +187 -0
  13. data/doc/DBD_SPEC.rdoc +88 -0
  14. data/doc/DBI_SPEC.rdoc +157 -0
  15. data/doc/homepage/contact.html +62 -0
  16. data/doc/homepage/development.html +124 -0
  17. data/doc/homepage/index.html +83 -0
  18. data/doc/homepage/ruby-dbi.css +91 -0
  19. data/examples/test1.pl +39 -0
  20. data/examples/test1.rb +20 -0
  21. data/examples/xmltest.rb +8 -0
  22. data/lib/dbd/Mysql.rb +137 -0
  23. data/lib/dbd/ODBC.rb +89 -0
  24. data/lib/dbd/Pg.rb +188 -0
  25. data/lib/dbd/SQLite.rb +97 -0
  26. data/lib/dbd/SQLite3.rb +124 -0
  27. data/lib/dbd/mysql/database.rb +405 -0
  28. data/lib/dbd/mysql/driver.rb +125 -0
  29. data/lib/dbd/mysql/statement.rb +188 -0
  30. data/lib/dbd/odbc/database.rb +128 -0
  31. data/lib/dbd/odbc/driver.rb +38 -0
  32. data/lib/dbd/odbc/statement.rb +137 -0
  33. data/lib/dbd/pg/database.rb +516 -0
  34. data/lib/dbd/pg/exec.rb +47 -0
  35. data/lib/dbd/pg/statement.rb +160 -0
  36. data/lib/dbd/pg/tuples.rb +121 -0
  37. data/lib/dbd/pg/type.rb +209 -0
  38. data/lib/dbd/sqlite/database.rb +151 -0
  39. data/lib/dbd/sqlite/statement.rb +125 -0
  40. data/lib/dbd/sqlite3/database.rb +201 -0
  41. data/lib/dbd/sqlite3/statement.rb +78 -0
  42. data/lib/dbi.rb +336 -0
  43. data/lib/dbi/base_classes.rb +12 -0
  44. data/lib/dbi/base_classes/database.rb +135 -0
  45. data/lib/dbi/base_classes/driver.rb +47 -0
  46. data/lib/dbi/base_classes/statement.rb +171 -0
  47. data/lib/dbi/binary.rb +25 -0
  48. data/lib/dbi/columninfo.rb +107 -0
  49. data/lib/dbi/exceptions.rb +65 -0
  50. data/lib/dbi/handles.rb +49 -0
  51. data/lib/dbi/handles/database.rb +241 -0
  52. data/lib/dbi/handles/driver.rb +60 -0
  53. data/lib/dbi/handles/statement.rb +408 -0
  54. data/lib/dbi/row.rb +269 -0
  55. data/lib/dbi/sql.rb +22 -0
  56. data/lib/dbi/sql/preparedstatement.rb +115 -0
  57. data/lib/dbi/sql_type_constants.rb +75 -0
  58. data/lib/dbi/trace.rb +91 -0
  59. data/lib/dbi/types.rb +218 -0
  60. data/lib/dbi/typeutil.rb +109 -0
  61. data/lib/dbi/utils.rb +60 -0
  62. data/lib/dbi/utils/date.rb +59 -0
  63. data/lib/dbi/utils/tableformatter.rb +112 -0
  64. data/lib/dbi/utils/time.rb +52 -0
  65. data/lib/dbi/utils/timestamp.rb +96 -0
  66. data/lib/dbi/utils/xmlformatter.rb +73 -0
  67. data/lib/dbi/version.rb +3 -0
  68. data/prototypes/types2.rb +237 -0
  69. data/readme.md +274 -0
  70. data/setup.rb +1585 -0
  71. data/test/DBD_TESTS +50 -0
  72. data/test/TESTING +16 -0
  73. data/test/dbd/general/test_database.rb +206 -0
  74. data/test/dbd/general/test_statement.rb +326 -0
  75. data/test/dbd/general/test_types.rb +296 -0
  76. data/test/dbd/mysql/base.rb +26 -0
  77. data/test/dbd/mysql/down.sql +19 -0
  78. data/test/dbd/mysql/test_blob.rb +18 -0
  79. data/test/dbd/mysql/test_new_methods.rb +7 -0
  80. data/test/dbd/mysql/test_patches.rb +111 -0
  81. data/test/dbd/mysql/up.sql +28 -0
  82. data/test/dbd/odbc/base.rb +30 -0
  83. data/test/dbd/odbc/down.sql +19 -0
  84. data/test/dbd/odbc/test_new_methods.rb +12 -0
  85. data/test/dbd/odbc/test_ping.rb +10 -0
  86. data/test/dbd/odbc/test_statement.rb +44 -0
  87. data/test/dbd/odbc/test_transactions.rb +58 -0
  88. data/test/dbd/odbc/up.sql +33 -0
  89. data/test/dbd/postgresql/base.rb +31 -0
  90. data/test/dbd/postgresql/down.sql +31 -0
  91. data/test/dbd/postgresql/test_arrays.rb +179 -0
  92. data/test/dbd/postgresql/test_async.rb +121 -0
  93. data/test/dbd/postgresql/test_blob.rb +36 -0
  94. data/test/dbd/postgresql/test_bytea.rb +87 -0
  95. data/test/dbd/postgresql/test_ping.rb +10 -0
  96. data/test/dbd/postgresql/test_timestamp.rb +77 -0
  97. data/test/dbd/postgresql/test_transactions.rb +58 -0
  98. data/test/dbd/postgresql/testdbipg.rb +307 -0
  99. data/test/dbd/postgresql/up.sql +60 -0
  100. data/test/dbd/sqlite/base.rb +32 -0
  101. data/test/dbd/sqlite/test_database.rb +30 -0
  102. data/test/dbd/sqlite/test_driver.rb +68 -0
  103. data/test/dbd/sqlite/test_statement.rb +112 -0
  104. data/test/dbd/sqlite/up.sql +25 -0
  105. data/test/dbd/sqlite3/base.rb +32 -0
  106. data/test/dbd/sqlite3/test_database.rb +77 -0
  107. data/test/dbd/sqlite3/test_driver.rb +67 -0
  108. data/test/dbd/sqlite3/test_statement.rb +88 -0
  109. data/test/dbd/sqlite3/up.sql +33 -0
  110. data/test/dbi/tc_columninfo.rb +94 -0
  111. data/test/dbi/tc_date.rb +88 -0
  112. data/test/dbi/tc_dbi.rb +184 -0
  113. data/test/dbi/tc_row.rb +256 -0
  114. data/test/dbi/tc_sqlbind.rb +168 -0
  115. data/test/dbi/tc_statementhandle.rb +29 -0
  116. data/test/dbi/tc_time.rb +77 -0
  117. data/test/dbi/tc_timestamp.rb +142 -0
  118. data/test/dbi/tc_types.rb +268 -0
  119. data/test/ts_dbd.rb +131 -0
  120. data/test/ts_dbi.rb +16 -0
  121. data/ydbi.gemspec +24 -0
  122. metadata +224 -0
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load_path = false
4
+ gems = false
5
+ redefined = false
6
+
7
+ # these clauses are for installations which have RUBYOPT=-rubygems, etc.
8
+ if Object.const_defined? "Gem"
9
+ redefined = true
10
+ module Kernel
11
+ alias gem_require require
12
+ alias require gem_original_require
13
+ end
14
+ end
15
+
16
+ begin
17
+ require 'dbi'
18
+ load_path = true
19
+ rescue LoadError => e
20
+ end
21
+
22
+ if Object.const_defined? "Gem" and redefined
23
+ module Kernel
24
+ alias gem_original_require require
25
+ alias require gem_require
26
+ end
27
+ end
28
+
29
+ begin
30
+ require 'rubygems'
31
+ gem 'dbi'
32
+ gems = true
33
+ rescue LoadError
34
+ rescue Gem::LoadError
35
+ end
36
+
37
+ puts "Your installation of DBI is broken" if gems and load_path
@@ -0,0 +1,60 @@
1
+ require 'rake_task_lib'
2
+ require 'dbi'
3
+
4
+ DBD_PACKAGES = Dir['lib/dbd/*.rb'].collect { |x| File.basename(x, '.rb') }
5
+
6
+ # creates a number of tasks like dbi:task_name, dbd_mysql:task_name, so on.
7
+ # Builds these out into an array that can be used as a prereq for other tasks.
8
+ def map_task(task_name)
9
+ namespaces = (['dbi'] + DBD_PACKAGES.collect { |x| dbd_namespace(x) }).flatten
10
+ namespaces.collect { |x| [x, task_name].join(":") }
11
+ end
12
+
13
+ task :package => (map_task("package") + map_task("gem"))
14
+ task :clobber_package => map_task("clobber_package")
15
+
16
+ desc 'Run interface tests (no database connectivity required)'
17
+ task :test_dbi do
18
+ ruby("test/ts_dbi.rb")
19
+ end
20
+
21
+ desc 'Run database-specific tests'
22
+ task :test_dbd do
23
+ ruby("test/ts_dbd.rb")
24
+ end
25
+
26
+ desc 'Run full test suite'
27
+ task :test => [:test_dbi, :test_dbd]
28
+
29
+ build_dbi_tasks
30
+
31
+ #
32
+ # There's probably a better way to do this, but here's a boilerplate spec that we dup and modify.
33
+ #
34
+
35
+ task :dbi => DEFAULT_TASKS.collect { |x| "dbi:#{x.to_s}" }
36
+
37
+ namespace :dbi do
38
+ code_files = %w(examples/**/* bin/dbi build/Rakefile.dbi.rb lib/dbi.rb lib/dbi/**/*.rb test/ts_dbi.rb test/dbi/*)
39
+
40
+ spec = boilerplate_spec
41
+ spec.name = 'dbi'
42
+ spec.version = DBI::VERSION
43
+ spec.test_file = 'test/ts_dbi.rb'
44
+ spec.executables = ['dbi', 'test_broken_dbi']
45
+ spec.files = gem_files(code_files)
46
+ spec.summary = 'A vendor independent interface for accessing databases, similar to Perl\'s DBI'
47
+ spec.description = 'A vendor independent interface for accessing databases, similar to Perl\'s DBI'
48
+ spec.add_dependency 'deprecated', '= 2.0.1'
49
+
50
+ build_package_tasks(spec, code_files)
51
+ end
52
+
53
+ DBD_PACKAGES.each do |dbd|
54
+ my_namespace = dbd_namespace(dbd)
55
+
56
+ task my_namespace => DEFAULT_TASKS.collect { |x| "#{my_namespace}:#{x.to_s}" }
57
+ namespace my_namespace do
58
+ build_dbd_tasks(dbd)
59
+ end
60
+ end
@@ -0,0 +1,187 @@
1
+ $:.unshift 'lib'
2
+ require 'rake'
3
+ require 'rubygems'
4
+ require 'rubygems/package_task'
5
+ require 'rake/packagetask'
6
+ require 'rdoc/task'
7
+
8
+
9
+ DEFAULT_TASKS = [:clobber_package, :package, :gem]
10
+
11
+ DBD_GEM_DEP_MAP = {
12
+ 'pg' => 'pg',
13
+ 'mysql' => 'mysql',
14
+ 'sqlite' => 'sqlite-ruby',
15
+ 'sqlite3' => 'sqlite3-ruby'
16
+ }
17
+
18
+ #
19
+ # Packaging
20
+ #
21
+
22
+ PACKAGE_FILES = %w(Rakefile build/rake_task_lib.rb setup.rb)
23
+ DOC_FILES = %w(readme.md LICENSE ChangeLog)
24
+ EXCLUSIONS = %w(test/sql.log)
25
+ DBD_FILES = %w(test/DBD_TESTS)
26
+
27
+ #
28
+ # some inlines
29
+ #
30
+
31
+ def gem_files(code_files)
32
+ (code_files + DOC_FILES).collect { |x| Dir[x] }.reject { |x| EXCLUSIONS.include? x }.flatten
33
+ end
34
+
35
+ def package_files(code_files)
36
+ code_files + DOC_FILES + PACKAGE_FILES
37
+ end
38
+
39
+ def build_package_tasks(spec, code_files)
40
+ Gem::PackageTask.new(spec) do |s|
41
+ end
42
+
43
+ Rake::PackageTask.new(spec.name, spec.version) do |p|
44
+ p.need_tar_gz = true
45
+ p.need_zip = true
46
+
47
+ package_files(code_files).each do |x|
48
+ p.package_files.include(x)
49
+ end
50
+
51
+ EXCLUSIONS.each do |x|
52
+ p.package_files.exclude(x)
53
+ end
54
+ end
55
+ end
56
+
57
+ def boilerplate_spec
58
+ gem = Gem::Specification.new
59
+ gem.authors = ['Erik Hollensbe', 'Christopher Maujean']
60
+ gem.email = 'ruby-dbi-users@rubyforge.org'
61
+ gem.homepage = 'http://www.rubyforge.org/projects/ruby-dbi'
62
+ gem.platform = Gem::Platform::RUBY
63
+ gem.has_rdoc = true
64
+ gem.extra_rdoc_files = DOC_FILES
65
+ gem.required_ruby_version = '>= 1.8.0'
66
+ gem.rubyforge_project = 'ruby-dbi'
67
+ return gem
68
+ end
69
+
70
+ # builds a dbd namespace from the DBD_PACKAGES hash
71
+ def dbd_namespace(dbd)
72
+ "dbd-" + dbd.to_s.downcase
73
+ end
74
+
75
+ def dbd_code_files(dbd)
76
+ code_files = [
77
+ "test/dbd/general/**",
78
+ File.join("test", "dbd", dbd.downcase == "pg" ? "postgresql" : dbd.downcase, "*"),
79
+ File.join("lib", "dbd", dbd + ".rb"),
80
+ "lib/dbd/#{dbd.downcase}/*.rb",
81
+ ] + DBD_FILES
82
+ end
83
+
84
+ def dbd_gem_files(code_files)
85
+ DBD_FILES + gem_files(code_files)
86
+ end
87
+
88
+ def dbd_package_files(code_files)
89
+ DBD_FILES + package_files(code_files)
90
+ end
91
+
92
+ def dbd_gem_spec(dbd, dbd_const, code_files)
93
+ spec = boilerplate_spec
94
+ spec.name = dbd_namespace(dbd)
95
+ spec.version = dbd_version(dbd_const)
96
+ spec.test_file = 'test/ts_dbd.rb'
97
+ spec.files = gem_files(code_files)
98
+ spec.summary = dbd_description(dbd_const)
99
+ spec.description = dbd_description(dbd_const)
100
+ spec.add_dependency 'dbi', '>= 0.4.0'
101
+
102
+ dcdbd = dbd.downcase
103
+
104
+ if DBD_GEM_DEP_MAP[dcdbd]
105
+ spec.add_dependency DBD_GEM_DEP_MAP[dcdbd]
106
+ end
107
+
108
+ return spec
109
+ end
110
+
111
+ def dbd_version(const)
112
+ DBI::DBD.const_get(const).const_get("VERSION")
113
+ end
114
+
115
+ def dbd_description(const)
116
+ DBI::DBD.const_get(const).const_get("DESCRIPTION")
117
+ end
118
+
119
+
120
+ def build_dbd_tasks(dbd)
121
+ task :default => DEFAULT_TASKS
122
+
123
+ begin
124
+ done = false
125
+ dbd_const = nil
126
+ Dir["lib/dbd/*.rb"].each do |dbd_file|
127
+ if File.basename(dbd_file.downcase, '.rb') == dbd.to_s.downcase
128
+ dbd_const = File.basename(dbd_file, '.rb')
129
+ require "dbd/#{dbd_const}"
130
+ done = true
131
+ end
132
+ end
133
+
134
+ abort "No DBD found even though we asked to make tasks for it" unless done
135
+
136
+ code_files = dbd_code_files(dbd_const)
137
+
138
+ spec = dbd_gem_spec(dbd, dbd_const, code_files)
139
+
140
+ build_package_tasks(spec, code_files)
141
+
142
+ # FIXME: convert to a rake_test_loader sooner or later
143
+ task :test do
144
+ ENV["DBTYPES"] = dbd
145
+ ruby "test/ts_dbd.rb"
146
+ end
147
+ rescue LoadError => e
148
+ DEFAULT_TASKS.each do |x|
149
+ task x do
150
+ end
151
+ end
152
+ warn "Skipping #{dbd_namespace(dbd)} because we can't require DBD"
153
+ end
154
+ end
155
+
156
+ def build_dbi_tasks
157
+ end
158
+
159
+ #
160
+ # basic tasks
161
+ #
162
+
163
+ task :dist => [:distclean, :package, :rdoc]
164
+ task :distclean => [:clobber_package, :clobber_rdoc]
165
+ task :clean => [:distclean]
166
+ task :default => [:test, :dist]
167
+
168
+ task :to_blog => [:clobber_rdoc, :rdoc] do
169
+ sh "rm -r $git/blog/content/docs/ruby-dbi && mv rdoc $git/blog/content/docs/ruby-dbi"
170
+ end
171
+
172
+ #
173
+ # Documentation
174
+ #
175
+
176
+ RDoc::Task.new do |rd|
177
+ rd.rdoc_dir = "rdoc"
178
+ rd.main = "README"
179
+ rd.rdoc_files.include("./README")
180
+ rd.rdoc_files.include("./ChangeLog")
181
+ rd.rdoc_files.include("./LICENSE")
182
+ rd.rdoc_files.include("./doc/**/*.rdoc")
183
+ rd.rdoc_files.include("./lib/**/*.rb")
184
+ rd.rdoc_files.include("./ext/**/*.c")
185
+ rd.options = %w(-a)
186
+ end
187
+
@@ -0,0 +1,88 @@
1
+ = DBD Specification Version 0.4.0
2
+ By Erik Hollensbe <erik@hollensbe.org>
3
+
4
+ == FOREWORD
5
+
6
+ DBI is still in a large state of flux. Previous versions of this
7
+ specification rarely reflected reality, and the 0.4.0 release is an
8
+ attempt to get the code and documentation in touch with each other to
9
+ better reflect said reality.
10
+
11
+ While this is a goal, nobody's perfect and there is still a lot of
12
+ code to check, sanitize, and otherwise clean up. If you find something
13
+ missing in these specifications while working on a new DBD or a patch
14
+ for DBI, please, do not do what everything else is doing; alert the
15
+ appropriate person to get the spec revised. Doing this will save
16
+ yourself (and the DBI authors) infinite amounts of time.
17
+
18
+ == WHAT A DBD IS
19
+
20
+ DBD stands for "DataBase Driver" and is the layer that DBI uses to interface
21
+ with the database. DBDs often employ a low level driver to do the real work
22
+ with the database, leaving the DBD itself to act as a medium between DBI and
23
+ that lower level API.
24
+
25
+ This allows a great deal of flexibility without having to sacrifice features
26
+ for compatibility. For example, instead of having one PostgreSQL DBD that
27
+ handles all version of PostgreSQL and attempts to limit it's functionality
28
+ based on what version it detects (a error-prone and time/design prohibitive
29
+ process), one can write two PostgreSQL DBD that handle the differences between
30
+ "new" and "old" postgres, all while talking to the same low-level driver (yet
31
+ leveraging different functionality). This method leads to cleaner internals and
32
+ puts the choice of which to use on the end-user, who is probably a lot more
33
+ informed about what features they want than your code.
34
+
35
+ One traditionally loads a DBD using the DBI.connect method (see DBD LOAD
36
+ PATHS below) which will attempt to load the DBD, connect to the database with
37
+ the arguments supplied and return a DatabaseHandle if successful. However, if
38
+ the DBD is written properly, requiring it directly without DBI's involvement
39
+ (or existence) should not be an issue.
40
+
41
+ == WHERE DBDs LIVE
42
+
43
+ DBDs have an expected require path to be loaded by DBI. DBI will attempt to
44
+ load the middle portion of the DBI.connect DSN provided.
45
+
46
+ Example: DBI.connect("dbi:Mysql:mydb") # requires 'dbd/Mysql'
47
+
48
+ Since rubygems potentially renders this path virtual, it is not OK to expect
49
+ this path physically exists in one spot on the filesystem. Many assuptions are
50
+ currently made about this and will be pruned in 0.6.0.
51
+
52
+ If you wish to create submodules for your DBD, create a directory in the 'dbd'
53
+ directory named the same as the DBD. (E.g., "dbd/Mysql" would have a directory
54
+ with files in it relating to the Mysql.rb file that DBI loads).
55
+
56
+ == HOW DBI INTERFACES WITH YOUR DBD
57
+
58
+ Your DBD will create classes representing a DBI::BaseDriver, DBI::BaseDatabase,
59
+ and DBI::BaseStatement. DBI will link these to DBI::DriverHandle,
60
+ DBI::DatabaseHandle, and DBI::StatementHandle respectively. Your classes will
61
+ be called by the Handle classes to retreive information to manipulate and send
62
+ to the user. This manipulation can be influenced in a number of ways.
63
+
64
+ It is strongly recommended you make the effort to read the RDoc for all six
65
+ of these classes, as they are the meat of this specification, not this
66
+ document.
67
+
68
+ == BUILDING A DBD FROM SCRATCH
69
+
70
+ For the purposes of this discussion, we'll call your driver 'Foo'.
71
+
72
+ Create your module, DBI::DBD::Foo. Store it somewhere in your load path under
73
+ dbd/Foo.rb.
74
+
75
+ Create classes Driver, Database, and Statement in this new namespace, which
76
+ inherit from DBI::BaseDriver, DBI::BaseDatabase, and DBI::BaseStatement.
77
+ Override (at mininum) the methods that return NotImplementedError in your new
78
+ classes.
79
+
80
+ Create a method in the root namespace named +driver_name+. This should return a
81
+ string with a short name for your driver, this key will be used in type
82
+ conversion.
83
+
84
+ Everything else is up to you, up to and including worrying about interacting
85
+ with the database.
86
+
87
+ At this point, you should be ready to test your driver. See test/DBD_TESTS for
88
+ information on how to configure that.
@@ -0,0 +1,157 @@
1
+ = DBI Interface Spec, for version 0.4.0
2
+
3
+ by Erik Hollensbe <erik@hollensbe.org>
4
+
5
+ == Foreword
6
+
7
+ DBI is still in a large state of flux. Previous versions of this
8
+ specification rarely reflected reality, and the 0.4.0 release is an
9
+ attempt to get the code and documentation more in sync.
10
+
11
+ While this is the goal, there is still a lot of
12
+ code to check, sanitize, and otherwise clean up. If you find something
13
+ missing in these specifications while working on a new DBD or a patch
14
+ for DBI, please bring it to our attention (in IRC or on the mailing list)
15
+ to get the spec revised. Doing this will save
16
+ yourself (and the DBI authors) a lot of time.
17
+
18
+ == Design
19
+
20
+ With DBI, there are the concepts of driver, database, and statement. The core
21
+ functionality for these concepts is provided by a database driver, or
22
+ DBD. DBI controls one or more drivers at once, a driver has databases, a
23
+ database may have statements.
24
+
25
+ DBI uses a delegation model to communicate with its DBDs through a
26
+ series of handles. When a connection to a database is requested, DBI contacts
27
+ the appropriate DBD and builds a handle in
28
+ its name that it aligns with a DBI base class for that concept. The
29
+ handle provided by the DBD is the first-class method of communication,
30
+ otherwise it resorts to calling the base class methods. This allows
31
+ DBI to provide a level of consistency unless the DBD author finds it
32
+ otherwise unnecessary.
33
+
34
+ For example: DBI will provide handy methods like fetch_all and
35
+ fetch_scroll which all leverage the fetch method in the base class,
36
+ and the fetch method must be implemented by the DBD. However, the DBD
37
+ may have an internal representation of fetch_scroll (as is the case
38
+ with the ODBC driver) that may be more suited to direct use, and
39
+ therefore DBI will never see the base class method. This is similar to
40
+ inheritance, but there is a distinct disconnect between the handles
41
+ and the base classes, intentionally so. This way the DBDs have no
42
+ access to the base class and DBI does all the delegation work. Also,
43
+ DBI has no idea what the DBD is doing underneath, nor does it need to
44
+ care as long as valid data is returned.
45
+
46
+ == Classes
47
+
48
+ These are the classes that make up the core of DBI and provide
49
+ various functionality:
50
+
51
+ === DBI
52
+ Core module, responsible for everything underneath it, kickstarting
53
+ connections and loading drivers.
54
+
55
+ === DBI::Row
56
+
57
+ Responsible for representing the result set and managing the type
58
+ conversion of the result set.
59
+
60
+ === DBI::Utils
61
+
62
+ Utility methods which propogate through the rest of DBI.
63
+
64
+ === DBI::SQL
65
+
66
+ Utility methods for working with SQL queries. Includes a
67
+ driver-independent SQL bind manager.
68
+
69
+ === DBI::ColumnInfo
70
+
71
+ Responsible for representing the information per column for both
72
+ queries and table descriptions.
73
+
74
+ === DBI::Type
75
+
76
+ Namespace for typecasting classes. These classes are provided with a
77
+ parse method which converts them to a native Ruby type from a string.
78
+
79
+ === DBI::TypeUtil
80
+
81
+ The inverse of DBI::Type, this provides functionality to turn native
82
+ Ruby types into a representation suitable for the DBD's queries.
83
+
84
+ === DBI::Binary
85
+
86
+ The representation of a BLOB/CLOB in a Ruby object. This will
87
+ eventually be rolled into DBI::Type::, but remains here currently for
88
+ compatibility purposes.
89
+
90
+ === DBI::Base* and DBI::*Handle
91
+
92
+ Please see the Design section above for the description of these modules.
93
+
94
+ == Exceptions
95
+
96
+ DBI has a slew of custom exceptions it uses to control program flow,
97
+ and alert the user to specific classes of problems.
98
+
99
+ They currently all live in the DBI namespace, although it's expected
100
+ that there will eventually be an exception namespace.
101
+
102
+ === DBI::Warning < RuntimeError
103
+ For important warnings such as data truncation, etc.
104
+
105
+ === DBI::Error < RuntimeError
106
+ Base class of all other error exceptions.
107
+ Rescue this to rescue all DBI errors.
108
+
109
+ === DBI::InterfaceError < DBI::Error
110
+ Exception for errors related to the DBI interface rather
111
+ than the database itself.
112
+
113
+ === DBI::NotImplementedError < DBI::InterfaceError
114
+ Exception raised if the DBD driver has not specified
115
+ a mandatory method.
116
+
117
+ === DBI::DatabaseError < DBI::Error
118
+ Exception for errors related to the database.
119
+
120
+ Has three attributes: ((|err|)), ((|errstr|)) and ((|state|)).
121
+
122
+ === DBI::DataError < DBI::DatabaseError
123
+ Exception for errors due to problems with the processed
124
+ data, such as division by zero, numeric value out of range, etc.
125
+
126
+ === DBI::OperationalError < DBI::DatabaseError
127
+ Exception for errors related to the database's operation which
128
+ are not necessarily under the control of the programmer. This would include
129
+ such things as unexpected disconnection, failure to find a datasource name,
130
+ failure to process a transaction, memory allocation errors, etc.
131
+
132
+ === DBI::IntegrityError < DBI::DatabaseError
133
+ Exception raised when the relational integrity of the database
134
+ is affected, such as when a foreign key constraint is violated.
135
+
136
+ === DBI::InternalError < DBI::DatabaseError
137
+ Exception raised when the database encounters an internal error,
138
+ such as a cursor not being valid anymore, or a transaction going out of
139
+ sync.
140
+
141
+ === DBI::ProgrammingError < DBI::DatabaseError
142
+ Exception raised for programming errors, e.g., table not found
143
+ or already exists, syntax error in SQL statement, wrong number
144
+ of parameters specified, etc.
145
+
146
+ === DBI::NotSupportedError < DBI::DatabaseError
147
+ Raised if, e.g., ((<commit>)) is called for a database that does not
148
+ support transactions.
149
+
150
+ == API
151
+
152
+ To save my sanity, I have joined the specification and the rdoc for
153
+ DBI. Please review the specification there.
154
+
155
+ If you wish to author your own DBD, please see DBD_SPEC.rdoc,
156
+ which is a more in-depth view of the communication between DBI and
157
+ DBDs.