dbi-dbrc 1.1.2-x86-mswin32-60

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.
data/CHANGES ADDED
@@ -0,0 +1,105 @@
1
+ == 1.1.2 - 18-Jul-2008
2
+ * Changed platform checking from RUBY_PLATFORM to Config::CONFIG['host_os']
3
+ so that other implementations won't choke.
4
+ * Updated the gemspec to add the sys-admin dependency.
5
+ * Added a rubyforge_project to the gemspec.
6
+ * Now has a separate gem for MS Windows.
7
+
8
+ == 1.1.1 - 2-Aug-2007
9
+ * DBRCError is now DBRC::Error.
10
+ * Added a Rakefile with tasks for installation and testing.
11
+ * Added the win32-dir library as a prerequisite for MS Windows.
12
+ * Removed the install.rb file. That's now handled by the Rakefile.
13
+ * Some refactoring in the constructor, including the elimination of
14
+ warnings that appeared when run with -w.
15
+ * Some doc and test updates.
16
+
17
+ == 1.1.0 - 19-Oct-2005
18
+ * Bug fix for MS Windows (there's no Win32 namespace for win32/file).
19
+ * Changed platform detection mechanism.
20
+
21
+ == 1.0.1 - 7-Oct-2005
22
+ * Improved the error message when an entry isn't found.
23
+
24
+ == 1.0.0 - 15-Jun-2005
25
+ * Ditches the use of 'etc'. Now requires the 'sys-admin' package as its
26
+ replacement (for all platforms).
27
+ * Moved project to RubyForge.
28
+ * Minor updates to tests, README and gemspec.
29
+ * Now hosted on RubyForge.
30
+
31
+ == 0.5.1 - 17-Mar-2005
32
+ * Removed the 'doc' directory completely, and moved the primary
33
+ documentation into the README file.
34
+ * Removed the INSTALL file. Moved the installation directions into the
35
+ README file.
36
+ * Moved the examples into a toplevel 'examples' directory.
37
+ * Made the README and CHANGES files rdoc friendly.
38
+ * Added a gemspec.
39
+
40
+ == 0.5.0 - 15-Oct-2004
41
+ * Added a YAML subclass. Use this if you want to store your information in
42
+ the .dbrc file in YAML format.
43
+ * On Win32 systems, the .dbrc file must now be "hidden". Also, it will
44
+ automatically decrypt/encrypt the file if it is encrypted. This also
45
+ means that the win32-file package is also required on Win32 systems.
46
+ * Massive refactoring of the XML subclass. It should work better now.
47
+ * Moved the YML and XML subclasses directly into the dbrc.rb file.
48
+ * For the aliases, you can now write as well as read.
49
+ * In lieu of the namespace fix for "timeout" in 1.8, I have renamed "time_out"
50
+ to simply "timeout". For backwards compatability, I have created an alias,
51
+ so you may still use the old method name. However, this means that you
52
+ should only use this package with 1.8.0 or later.
53
+ * Removed the dbrc.html file. You can generate this on your own if you wish
54
+ using rdtool.
55
+ * Test suite changes.
56
+
57
+ == 0.4.0 - 3-Sep-2004
58
+ * Removed redundant error handling for cases when the database and/or login
59
+ are not found.
60
+ * Added an XML subclass. Use this if you want to store your information in
61
+ the .dbrc file in XML format.
62
+
63
+ == 0.3.0 - 26-Oct-2003
64
+ * Win32 support added. Requires the win32-etc package.
65
+ * rd doc separated from source. Moved to 'doc' directory.
66
+ * Documentation updates and corrections.
67
+ * Minor test suite tweaks for Win32 systems.
68
+
69
+ == 0.2.1 - 28-Aug-2003
70
+ * Removed VERSION class method. Just use the constant.
71
+ * Bug fix with regards to split and Ruby 1.8. Thanks Michael Garriss.
72
+ * Changed 'changelog' to 'CHANGES'.
73
+ * Added a vanilla test script (test.rb)
74
+ * Minor code optimization (IO.foreach)
75
+ * Test unit cleanup
76
+ * Minor internal directory layout and doc changes
77
+
78
+ == 0.2.0 - 13-Jan-2003
79
+ * DBRC class now under the DBI module namespace
80
+ * Changed "timeout" to "time_out" to avoid confusion with the timeout
81
+ module.
82
+ * The 'time_out', 'max_reconn', and 'interval' methods now return Integers,
83
+ rather than Strings.
84
+ * Only the database, user and password fields are required now within the
85
+ .dbrc file. The driver, time_out and max_reconn entries can be left blank
86
+ without causing an error. Note that the 'dsn' method will return 'nil'
87
+ if the driver isn't set.
88
+ * Added a DBRCException class instead of just raising an error string.
89
+ * Changed 'db' method to 'database' (but 'db' is an alias)
90
+ * Changed 'max_reconn' method to 'maximum_reconnects' (but 'max_reconn'
91
+ is an alias')
92
+ * Added 'passwd' alias for 'password' method
93
+ * Added a VERSION class method
94
+ * Methods that should have been private are now private
95
+ * Internal directory layout change
96
+ * Tests added
97
+ * Install script improved
98
+ * Documentation additions, including plain text doc
99
+
100
+ == 0.1.1 - 26-Jul-2002
101
+ * Added 'dsn()' method
102
+ * Minor documentation additions
103
+
104
+ == 0.1.0 - 26-Jul-2002
105
+ * Initial release
@@ -0,0 +1,16 @@
1
+ * MANIFEST
2
+ * CHANGES
3
+ * README
4
+ * Rakefile
5
+ * dbi-dbrc.gemspec
6
+ * lib/dbi/dbrc.rb
7
+ * examples/plain/.dbrc
8
+ * examples/plain/test.rb
9
+ * examples/xml_examples/.dbrc
10
+ * examples/xml_examples/test_xml.rb
11
+ * examples/yml_examples/.dbrc
12
+ * examples/yml_examples/test_yml.rb
13
+ * test/ts_all.rb
14
+ * test/tc_dbrc.rb
15
+ * test/tc_dbrc_xml.rb
16
+ * test/tc_dbrc_yml.rb
data/README ADDED
@@ -0,0 +1,250 @@
1
+ == Description
2
+ This is a supplement to the dbi module, allowing you to avoid hard-coding
3
+ passwords in your programs that make database connections.
4
+
5
+ == Requirements
6
+ * Ruby 1.8.2 or later
7
+ * sys-admin
8
+ * win32-file (MS Windows only)
9
+ * win32-dir (MS Windows only)
10
+
11
+ == Synopsis
12
+ require 'dbi/dbrc'
13
+ include DBI
14
+
15
+ dbrc = DBRC.new('mydb')
16
+
17
+ or
18
+
19
+ dbrc = DBRC.new('mydb', 'someUser')
20
+
21
+ puts dbrc.db
22
+ puts dbrc.user
23
+ puts dbrc.driver
24
+ puts dbrc.timeout
25
+ puts dbrc.max_reconn
26
+ puts dbrc.interval
27
+ puts dbrc.dsn
28
+
29
+ dbh = DBI.connect(dbrc.dsn, dbrc.user, dbrc.password)
30
+
31
+ == Installation
32
+ rake test (optional)
33
+ rake install (non-gem) or rake install_gem (gem)
34
+
35
+ == Notes on the .dbrc file
36
+ This module relies on a file in your home directory called ".dbrc", and it
37
+ is meant to be analogous to the ".netrc" file used by programs such as
38
+ telnet. The .dbrc file has several conditions that must be met by the
39
+ module or it will fail:
40
+
41
+ * Permissions must be set to 600 (Unix only).
42
+ * Must be hidden (MS Windows only).
43
+ * Must be owned by the current user.
44
+ * Must have database, user and password. Other fields are optional.
45
+ * Must be in the following space-separated format (in the 'plain' version):
46
+
47
+ database user password driver timeout maximum_reconnects interval
48
+
49
+ e.g. mydb dan mypass oracle 10 2 30
50
+
51
+ You may include comments in the .dbrc file by starting the line with a
52
+ "#" symbol.
53
+
54
+ A failure in any of the rules mentioned above will result in a DBRC::Error
55
+ being raised. In addition, the file may also be encrypted on MS Windows
56
+ systems, in which case the file will automatically be (temporarily)
57
+ decrypted.
58
+
59
+ The format for XML (using the example above) is as follows:
60
+
61
+ <dbrc>
62
+ <database name="mydb">
63
+ <user>dan</user>
64
+ <password>mypass</password>
65
+ <driver>oracle</driver>
66
+ <interval>30</interval>
67
+ <timeout>10</timeout>
68
+ <maximum_reconnects>2</maximum_reconnects>
69
+ </database>
70
+ </dbrc>
71
+
72
+ The format for YAML is as follows:
73
+
74
+ - mydb:
75
+ user: dan
76
+ password: mypass
77
+ driver: oracle
78
+ interval: 30
79
+ timeout: 10
80
+ max_reconn: 2
81
+
82
+ == Constants
83
+ VERSION
84
+ The current version of this packages, returned as a String.
85
+
86
+ == Class Methods
87
+ DBRC.new(db, user=nil, dir=nil)
88
+ The constructor takes one to three arguments. The first argument is the
89
+ database name. This *must* be provided. If only the database name is
90
+ passed, the module will look for the first database entry in the .dbrc
91
+ file that matches.
92
+
93
+ The second argument, a user name, is optional. If it is passed, the
94
+ module will look for the first entry in the .dbrc file where both the
95
+ database *and* user name match.
96
+
97
+ The third argument, also optional, specifies the directory where DBRC will
98
+ look for the .dbrc file. By default, it looks in the pwuid (present
99
+ working user id) home directory. The rules for a .dbrc file still apply.
100
+
101
+ MS Windows users should read the "Notes" section for how your home directory
102
+ is determined.
103
+
104
+ == Instance Methods
105
+ DBRC#database
106
+ The name of the database. Note that the same entry can appear more than
107
+ once, presumably because you have multiple user id's for the same
108
+ database.
109
+
110
+ DBRC#db
111
+ An alias for DBRC#database.
112
+
113
+ DBRC#database=(database)
114
+ Sets the database to +database+. This is generally discouraged because
115
+ it does not automatically reset the dsn.
116
+
117
+ DBRC#db=(database)
118
+ An alias for DBRC#database=.
119
+
120
+ DBRC#user
121
+ A valid user name for that database.
122
+
123
+ DBRC#user=(user)
124
+ Sets the user name to +user+.
125
+
126
+ DBRC#password
127
+ The password for that user.
128
+
129
+ DBRC#passwd
130
+ An alias for DBRC#password.
131
+
132
+ DBRC#password=(password)
133
+ Sets the password to +password+.
134
+
135
+ DBRC#passwd=(password)
136
+ An alias for DBRC#password=.
137
+
138
+ DBRC#driver
139
+ The driver type for that database (Oracle, MySql, etc).
140
+
141
+ DBRC#driver=(driver)
142
+ Sets the driver to +driver+. This use is discouraged because it does
143
+ not reset the dsn.
144
+
145
+ DBRC#timeout
146
+ The timeout period for a connection before the attempt is dropped.
147
+
148
+ DBRC#time_out
149
+ An alias for DBRC#timeout, provided purely for the sake of backwards
150
+ compatability.
151
+
152
+ DBRC#timeout=(int)
153
+ Sets the timeout value to +int+.
154
+
155
+ DBRC#maximum_reconnects
156
+ The maximum number of reconnect attempts that should be made for the the
157
+ database. Presumablly, you would use this with a "retry" within a rescue
158
+ block.
159
+
160
+ DBRC#max_reconn
161
+ An alias for DBRC#maximum_reconnects.
162
+
163
+ DBRC#maximum_reconnects=(max)
164
+ Sets the maximum number of reconnect attempts to +max+.
165
+
166
+ DBRC#max_reconn=(max)
167
+ An alias for DBRC#maximum_reconnects.
168
+
169
+ DBRC#interval
170
+ The number of seconds to wait before attempting to reconnect to the database
171
+ again should a network/database glitch occur.
172
+
173
+ DBRC#interval=(int)
174
+ Sets the interval seconds between connection attempts.
175
+
176
+ DBRC#dsn
177
+ Returns a string in "dbi:<driver>:<database>" format.
178
+
179
+ DBRC#dsn=(dsn)
180
+ Sets the dsn string to +dsn+. This method is discouraged because it does
181
+ not automatically reset the driver or database.
182
+
183
+ == Canonical Example
184
+ # This is a basic template for how I do things:
185
+
186
+ require 'dbi/dbrc'
187
+ require 'timeout'
188
+
189
+ db = DBI::DBRC.new("somedb")
190
+ n = db.max_reconn
191
+
192
+ begin
193
+ timeout(db.time_out){
194
+ DBI.connect(db.dsn, db.user, db.passwd)
195
+ }
196
+ rescue DBI::Error
197
+ n -= 1
198
+ sleep db.interval if n > 0
199
+ retry if n > 0
200
+ raise
201
+ rescue TimeoutError
202
+ # handle timeout error
203
+ end
204
+
205
+ == Notes for MS Windows Users
206
+ The 'home' directory for Win32 users is determined by ENV['USERPROFILE'].
207
+ If that is not set, ENV['HOME'] is used. If that is not set, then
208
+ 'C:\Documents and Settings\user_name' is used.
209
+
210
+ To make your file hidden, right click on the .dbrc file in your Explorer
211
+ window, select "Properties" and check the "Hidden" checkbox.
212
+
213
+ I was going to require that the .dbrc file be encrypted on MS Windows,
214
+ but that may require an official "certificate", assigned to you by a third
215
+ party, which is a bit much to expect. However, if the file is encrypted,
216
+ DBRC will attempt to decrypt it, parse it, and encrypt it again when done
217
+ parsing.
218
+
219
+ == Notes on running the test suite
220
+ I cannot guarantee that the .dbrc files under the +examples+
221
+ subdirectories maintain the appropriate properties. This can cause
222
+ failures for the test suite (which uses these files).
223
+
224
+ The only solution is to perform a 'chmod 600 .dbrc' (on Unix) or set
225
+ the properties to 'hidden' (on MS Windows) manually, for the file in
226
+ question.
227
+
228
+ == Summary
229
+ These "methods" don't really do anything. They're simply meant as a
230
+ convenience mechanism for you dbi connections, plus a little bit of
231
+ obfuscation (for passwords).
232
+
233
+ == Adding your own configuration
234
+ If you want to add your own type of configuration file, you can still use
235
+ the dbi-dbrc package. All you need to do is:
236
+
237
+ * subclass DBRC
238
+ * redefine the +parse_dbrc_config_file+ method (a private method).
239
+
240
+ Take a look at the XML and YML subclasses in dbrc.rb for two examples that
241
+ you can work from.
242
+
243
+ == Known Bugs
244
+ I'm not positive about the dsn strings for databases other than Oracle.
245
+ If it's not correct, please let me know.
246
+
247
+ == Author
248
+ Daniel J. Berger
249
+ djberg96 at nospam at gmail dot com
250
+ imperator on IRC (irc.freenode.net)
@@ -0,0 +1,21 @@
1
+ ###########################################################################
2
+ # test.rb
3
+ #
4
+ # This script is provided for those without TestUnit installed and/or for
5
+ # general futzing.
6
+ ###########################################################################
7
+ if File.basename(Dir.pwd) == "plain"
8
+ Dir.chdir "../.."
9
+ $LOAD_PATH.unshift Dir.pwd + "/lib"
10
+ Dir.chdir "examples/plain"
11
+ end
12
+
13
+ require "pp"
14
+ require "dbi/dbrc"
15
+ include DBI
16
+
17
+ puts "VERSION: " + DBRC::VERSION
18
+
19
+ db = DBRC.new("foo","user1",Dir.pwd)
20
+
21
+ pp db
@@ -0,0 +1,28 @@
1
+ #######################################################################
2
+ # test_xml.rb
3
+ #
4
+ # Simple test script that uses the DBRC::XML subclass.
5
+ #######################################################################
6
+ if File.basename(Dir.pwd) == "xml"
7
+ Dir.chdir "../.."
8
+ $LOAD_PATH.unshift Dir.pwd + "/lib"
9
+ Dir.chdir "examples/xml"
10
+ end
11
+
12
+ require "dbi/dbrc"
13
+ require "pp"
14
+ include DBI
15
+
16
+ puts "VERSION: " + DBRC::XML::VERSION
17
+
18
+ # Use the .dbrc file in this directory
19
+ db1 = DBRC::XML.new("foo",nil,Dir.pwd) # Get first entry found for 'foo'
20
+ db2 = DBRC::XML.new("foo","user1",Dir.pwd) # Specify user
21
+
22
+ puts "First entry found for 'foo': "
23
+ pp db1
24
+ puts "=" * 20
25
+
26
+ puts "Entry for 'foo' with user 'bar': "
27
+ pp db2
28
+ puts "=" * 20
@@ -0,0 +1,28 @@
1
+ #######################################################################
2
+ # test_xml.rb
3
+ #
4
+ # Simple test script that uses the DBRC::XML subclass.
5
+ #######################################################################
6
+ if File.basename(Dir.pwd) == "yml"
7
+ Dir.chdir "../.."
8
+ $LOAD_PATH.unshift Dir.pwd + "/lib"
9
+ Dir.chdir "examples/yml"
10
+ end
11
+
12
+ require "dbi/dbrc"
13
+ require "pp"
14
+ include DBI
15
+
16
+ puts "VERSION: " + DBRC::YML::VERSION
17
+
18
+ # Use the .dbrc file in this directory
19
+ db1 = DBRC::YML.new("foo",nil,Dir.pwd) # Get first entry found for 'foo'
20
+ db2 = DBRC::YML.new("foo","user1",Dir.pwd) # Specify user
21
+
22
+ puts "First entry found for 'foo': "
23
+ pp db1
24
+ puts "=" * 20
25
+
26
+ puts "Entry for 'foo' with user 'bar': "
27
+ pp db2
28
+ puts "=" * 20
@@ -0,0 +1,231 @@
1
+ require 'rbconfig'
2
+
3
+ if Config::CONFIG['host_os'].match('mswin')
4
+ require 'win32/file'
5
+ require 'win32/dir'
6
+ end
7
+
8
+ require 'sys/admin'
9
+ include Sys
10
+
11
+ # The DBI module serves as a namespace only.
12
+ module DBI
13
+
14
+ # The DBRC class encapsulates a database resource config file.
15
+ class DBRC
16
+
17
+ # This error is raised if anything fails trying to read the config file.
18
+ # the error that is raised.
19
+ class Error < StandardError; end
20
+
21
+ VERSION = '1.1.2'
22
+ attr_accessor :database, :user, :password, :driver, :dsn
23
+ attr_accessor :maximum_reconnects, :timeout, :interval, :dbrc_dir
24
+
25
+ # Returns a new DBRC object. The contents of the object depend on the
26
+ # arguments passed to the constructor. If only a database name is
27
+ # passed, then the first entry found in the .dbrc file that matches that
28
+ # database is parsed. If a user name is also included, then the first
29
+ # entry that matches both the database and user name is parsed.
30
+ #
31
+ # If a directory is passed as the third argument, then DBRC will look
32
+ # in that directory, instead of the default directory, for the .dbrc
33
+ # file.
34
+ #
35
+ # If an entry cannot be found for the database, or database plus user
36
+ # combination, then a Error is raised. If the .dbrc file cannot
37
+ # be found, or is setup improperly with regards to permissions or
38
+ # properties, a Error is raised.
39
+ #
40
+ def initialize(database, user=nil, dbrc_dir=nil)
41
+ if dbrc_dir.nil?
42
+ if RUBY_PLATFORM.match('mswin')
43
+ home = ENV['USERPROFILE'] || ENV['HOME']
44
+ file = nil
45
+
46
+ if home
47
+ file = File.join(home, '.dbrc')
48
+ else
49
+ file = File.join(File.basename(Dir::APPDATA), '.dbrc')
50
+ end
51
+
52
+ @dbrc_file = file
53
+ else
54
+ @dbrc_file = File.join(Admin.get_user(Process.uid).dir, '.dbrc')
55
+ end
56
+ else
57
+ @dbrc_file = File.join(dbrc_dir, '.dbrc')
58
+ end
59
+
60
+ @database = database
61
+ @user = user
62
+ encrypted = false # Win32 only
63
+
64
+ @driver = nil
65
+ @interval = nil
66
+ @timeout = nil
67
+ @maximum_reconnects = nil
68
+
69
+ check_file()
70
+
71
+ # If on Win32 and the file is encrypted, decrypt it.
72
+ if RUBY_PLATFORM.match("mswin") && File.encrypted?(@dbrc_file)
73
+ encrypted = true
74
+ File.decrypt(@dbrc_file)
75
+ end
76
+
77
+ parse_dbrc_config_file()
78
+ validate_data()
79
+ convert_numeric_strings()
80
+ create_dsn_string()
81
+
82
+ # If on Win32 and the file was encrypted, re-encrypt it
83
+ if RUBY_PLATFORM.match("mswin") && encrypted
84
+ File.encrypt(@dbrc_file)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ # Ensure that the user/password has been set
91
+ def validate_data
92
+ unless @user
93
+ raise Error, "no user found associated with #{@database}"
94
+ end
95
+
96
+ unless @password
97
+ raise Error, "password not defined for #{@user}@#{@database}"
98
+ end
99
+ end
100
+
101
+ # Converts strings that should be numbers into actual numbers
102
+ def convert_numeric_strings
103
+ @interval = @interval.to_i if @interval
104
+ @timeout = @timeout.to_i if @timeout
105
+ @maximum_reconnects = @maximum_reconnects.to_i if @maximum_reconnects
106
+ end
107
+
108
+ # Create the dsn string if the driver is defined
109
+ def create_dsn_string
110
+ @dsn = "dbi:#{@driver}:#{@database}" if @driver
111
+ end
112
+
113
+ # Check ownership and permissions
114
+ def check_file(file=@dbrc_file)
115
+ File.open(file){ |f|
116
+
117
+ # Permissions must be set to 600 or better on Unix systems.
118
+ # Must be hidden on Win32 systems.
119
+ if RUBY_PLATFORM.match("mswin")
120
+ unless File.hidden?(file)
121
+ raise Error, "The .dbrc file must be hidden"
122
+ end
123
+ else
124
+ unless (f.stat.mode & 077) == 0
125
+ raise Error, "Bad .dbrc file permissions"
126
+ end
127
+ end
128
+
129
+ # Only the owner may use it
130
+ unless f.stat.owned?
131
+ raise Error, "Not owner of .dbrc file"
132
+ end
133
+ }
134
+ end
135
+
136
+ # Parse the text out of the .dbrc file. This is the only method you
137
+ # need to redefine if writing your own config handler.
138
+ def parse_dbrc_config_file(file=@dbrc_file)
139
+ IO.foreach(file){ |line|
140
+ next if line =~ /^#/ # Ignore comments
141
+ db, user, pwd, driver, timeout, max, interval = line.split
142
+
143
+ next unless @database == db
144
+
145
+ if @user
146
+ next unless @user == user
147
+ end
148
+
149
+ @user = user
150
+ @password = pwd
151
+ @driver = driver
152
+ @timeout = timeout
153
+ @maximum_reconnects = max
154
+ @interval = interval
155
+ return
156
+ }
157
+
158
+ # If we reach here it means the database and/or user wasn't found
159
+ if @user
160
+ err = "no record found for #{@user}@#{@database}"
161
+ else
162
+ err = "no record found for #{@database}"
163
+ end
164
+
165
+ raise Error, err
166
+ end
167
+
168
+ alias_method(:db,:database)
169
+ alias_method(:db=,:database=)
170
+ alias_method(:passwd,:password)
171
+ alias_method(:passwd=,:password=)
172
+ alias_method(:max_reconn,:maximum_reconnects)
173
+ alias_method(:max_reconn=,:maximum_reconnects=)
174
+ alias_method(:time_out,:timeout)
175
+ alias_method(:time_out=,:timeout=)
176
+ end
177
+
178
+ # A subclass of DBRC designed to handle .dbrc files in XML format. The
179
+ # public methods of this class are identical to DBRC.
180
+ class XML < DBRC
181
+ require "rexml/document"
182
+ include REXML
183
+ private
184
+ def parse_dbrc_config_file(file=@dbrc_file)
185
+ doc = Document.new(File.new(file))
186
+ fields = %w/user password driver interval timeout maximum_reconnects/
187
+ doc.elements.each("/dbrc/database"){ |element|
188
+ next unless element.attributes["name"] == database
189
+ if @user
190
+ next unless element.elements["user"].text == @user
191
+ end
192
+ fields.each{ |field|
193
+ val = element.elements[field]
194
+ unless val.nil?
195
+ send("#{field}=",val.text)
196
+ end
197
+ }
198
+ return
199
+ }
200
+ # If we reach here it means the database and/or user wasn't found
201
+ raise Error, "No record found for #{@user}@#{@database}"
202
+ end
203
+ end
204
+
205
+ # A subclass of DBRC designed to handle .dbrc files in YAML format. The
206
+ # public methods of this class are identical to DBRC.
207
+ class YML < DBRC
208
+ require "yaml"
209
+ private
210
+ def parse_dbrc_config_file(file=@dbrc_file)
211
+ config = YAML.load(File.open(file))
212
+ config.each{ |hash|
213
+ hash.each{ |db,info|
214
+ next unless db == @database
215
+ if @user
216
+ next unless @user == info["user"]
217
+ end
218
+ @user = info["user"]
219
+ @password = info["password"]
220
+ @driver = info["driver"]
221
+ @interval = info["interval"]
222
+ @timeout = info["timeout"]
223
+ @maximum_reconnects = info["max_reconn"]
224
+ return
225
+ }
226
+ }
227
+ # If we reach this point, it means the database wasn't found
228
+ raise Error, "No entry found for #{@user}@#{@database}"
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,178 @@
1
+ #########################################################################
2
+ # tc_dbrc.rb
3
+ #
4
+ # Test suite for the base class of DBI::DBRC. This test case should be
5
+ # run via the 'rake test' task.
6
+ #########################################################################
7
+ require 'dbi/dbrc'
8
+ require 'test/unit'
9
+ include DBI
10
+
11
+ class TC_DBRC < Test::Unit::TestCase
12
+ def setup
13
+ Dir.chdir('test') if File.basename(Dir.pwd) != 'test'
14
+
15
+ @dir = "../examples/plain"
16
+ @file = File.join(@dir, '.dbrc')
17
+ @db1 = "foo"
18
+ @db2 = "bar"
19
+ @user1 = "user1"
20
+ @user2 = "user2"
21
+ @db_bad = "blah" # Doesn't exist
22
+ @user_bad = "user8" # Doesn't exist
23
+
24
+ if File::ALT_SEPARATOR
25
+ File.set_attr(@file, File::HIDDEN)
26
+ else
27
+ File.chmod(0600, @file)
28
+ end
29
+
30
+ @dbrc = DBRC.new(@db1, nil, @dir)
31
+ end
32
+
33
+ def test_version
34
+ assert_equal("1.1.2", DBRC::VERSION)
35
+ end
36
+
37
+ def test_bad_dbrc_properties
38
+ if File::ALT_SEPARATOR
39
+ File.unset_attr(@file, File::HIDDEN)
40
+ assert_raises(DBRC::Error){ DBRC.new(@db1, @user1, @dir) }
41
+ else
42
+ File.chmod(0555,@file)
43
+ assert_raises(DBRC::Error){ DBRC.new(@db1, @user1, @dir) }
44
+ end
45
+ end
46
+
47
+ def test_constructor
48
+ assert_raises(ArgumentError){ DBRC.new }
49
+ assert_nothing_raised{ DBRC.new(@db1, @user1, @dir) }
50
+ assert_nothing_raised{ DBRC.new(@db1, nil, @dir) }
51
+ end
52
+
53
+ def test_bad_database
54
+ assert_raises(DBRC::Error){ DBRC.new(@db_bad, nil, @dir) }
55
+ end
56
+
57
+ def test_bad_user
58
+ assert_raises(DBRC::Error){ DBRC.new(@db1, @user_bad, @dir) }
59
+ end
60
+
61
+ def test_database
62
+ assert_respond_to(@dbrc, :database)
63
+ assert_respond_to(@dbrc, :database=)
64
+ assert_respond_to(@dbrc, :db)
65
+ assert_respond_to(@dbrc, :db=)
66
+ assert_kind_of(String, @dbrc.db)
67
+ end
68
+
69
+ def test_dsn
70
+ assert_respond_to(@dbrc, :dsn)
71
+ assert_respond_to(@dbrc, :dsn=)
72
+ end
73
+
74
+ def test_user
75
+ assert_respond_to(@dbrc, :user)
76
+ assert_respond_to(@dbrc, :user=)
77
+ assert_kind_of(String, @dbrc.user)
78
+ end
79
+
80
+ def test_password
81
+ assert_respond_to(@dbrc, :password)
82
+ assert_respond_to(@dbrc, :password=)
83
+ assert_respond_to(@dbrc, :passwd)
84
+ assert_respond_to(@dbrc, :passwd=)
85
+ assert_kind_of(String, @dbrc.password)
86
+ end
87
+
88
+ def test_driver
89
+ assert_respond_to(@dbrc, :driver)
90
+ assert_respond_to(@dbrc, :driver=)
91
+ assert_kind_of(String, @dbrc.driver)
92
+ end
93
+
94
+ def test_interval
95
+ assert_respond_to(@dbrc, :interval)
96
+ assert_respond_to(@dbrc, :interval=)
97
+ assert_kind_of(Fixnum, @dbrc.interval)
98
+ end
99
+
100
+ def test_timeout
101
+ assert_respond_to(@dbrc, :timeout)
102
+ assert_respond_to(@dbrc, :timeout=)
103
+ assert_respond_to(@dbrc, :time_out)
104
+ assert_respond_to(@dbrc, :time_out=)
105
+ assert_kind_of(Fixnum, @dbrc.timeout)
106
+ end
107
+
108
+ def test_max_reconn
109
+ assert_respond_to(@dbrc, :max_reconn)
110
+ assert_respond_to(@dbrc, :max_reconn=)
111
+ assert_respond_to(@dbrc, :maximum_reconnects)
112
+ assert_respond_to(@dbrc, :maximum_reconnects=)
113
+ assert_kind_of(Fixnum, @dbrc.maximum_reconnects)
114
+ end
115
+
116
+ def test_sample_values
117
+ assert_equal("foo", @dbrc.database)
118
+ assert_equal("user1", @dbrc.user)
119
+ assert_equal("pwd1", @dbrc.passwd)
120
+ assert_equal("Oracle", @dbrc.driver)
121
+ assert_equal(60, @dbrc.interval)
122
+ assert_equal(40, @dbrc.timeout)
123
+ assert_equal(3, @dbrc.max_reconn)
124
+ assert_equal("dbi:Oracle:foo", @dbrc.dsn)
125
+ end
126
+
127
+ # Same database, different user
128
+ def test_duplicate_database
129
+ db = DBRC.new("foo", "user2", @dir)
130
+ assert_equal("user2", db.user)
131
+ assert_equal("pwd2", db.passwd)
132
+ assert_equal("OCI8", db.driver)
133
+ assert_equal(60, db.interval)
134
+ assert_equal(60, db.timeout)
135
+ assert_equal(4, db.max_reconn)
136
+ assert_equal("dbi:OCI8:foo", db.dsn)
137
+ end
138
+
139
+ # Different database, different user
140
+ def test_different_database
141
+ db = DBRC.new("bar", "user1", @dir)
142
+ assert_equal("user1", db.user)
143
+ assert_equal("pwd3", db.passwd)
144
+ assert_equal("Oracle", db.driver)
145
+ assert_equal(30, db.interval)
146
+ assert_equal(30, db.timeout)
147
+ assert_equal(2, db.max_reconn)
148
+ assert_equal("dbi:Oracle:bar", db.dsn)
149
+ end
150
+
151
+ # A database with only a couple fields defined
152
+ def test_nil_values
153
+ db = DBRC.new("baz", "user3", @dir)
154
+ assert_equal("user3", db.user)
155
+ assert_equal("pwd4", db.passwd)
156
+ assert_nil(db.driver)
157
+ assert_nil(db.interval)
158
+ assert_nil(db.timeout)
159
+ assert_nil(db.max_reconn)
160
+ assert_nil(db.dsn)
161
+ end
162
+
163
+ def teardown
164
+ @dir = nil
165
+ @db1 = nil
166
+ @db2 = nil
167
+ @user1 = nil
168
+ @user2 = nil
169
+ @db_bad = nil
170
+ @user_bad = nil
171
+ @dbrc = nil
172
+ if File::ALT_SEPARATOR
173
+ File.set_attr(@file, File::HIDDEN)
174
+ else
175
+ File.chmod(0600, @file)
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,160 @@
1
+ ########################################################################
2
+ # tc_dbrc_xml.rb
3
+ #
4
+ # Test suite for the XML specific version of DBI::DBRC. This test case
5
+ # should be run via the 'rake test' task.
6
+ ########################################################################
7
+ require "dbi/dbrc"
8
+ require "test/unit"
9
+ require "rexml/document"
10
+ include REXML
11
+ include DBI
12
+
13
+ class TC_DBRC_XML < Test::Unit::TestCase
14
+ def setup
15
+ Dir.chdir('test') if File.basename(Dir.pwd) != 'test'
16
+ @dir = "../examples/xml"
17
+ @file = File.join(@dir, ".dbrc")
18
+ @db1 = "foo"
19
+ @db2 = "bar"
20
+ @user1 = "user1"
21
+ @user2 = "user2"
22
+ @db_bad = "blah" # Doesn't exist
23
+ @user_bad = "user8" # Doesn't exist
24
+
25
+ if File::ALT_SEPARATOR
26
+ File.set_attr(@file, File::HIDDEN)
27
+ else
28
+ File.chmod(0600, @file)
29
+ end
30
+
31
+ @dbrc = DBRC::XML.new(@db1, nil, @dir)
32
+ end
33
+
34
+ def test_constructor
35
+ assert_raises(ArgumentError){ DBRC::XML.new }
36
+ assert_nothing_raised{ DBRC::XML.new(@db1, @user1, @dir) }
37
+ assert_nothing_raised{ DBRC::XML.new(@db1, nil, @dir) }
38
+ end
39
+
40
+ def test_bad_database
41
+ assert_raises(DBRC::Error){ DBRC::XML.new(@db_bad, nil, @dir) }
42
+ end
43
+
44
+ def test_bad_user
45
+ assert_raises(DBRC::Error){ DBRC::XML.new(@db1, @user_bad, @dir) }
46
+ end
47
+
48
+ def test_database
49
+ assert_respond_to(@dbrc, :database)
50
+ assert_respond_to(@dbrc, :database=)
51
+ assert_respond_to(@dbrc, :db)
52
+ assert_respond_to(@dbrc, :db=)
53
+ assert_kind_of(String, @dbrc.db)
54
+ end
55
+
56
+ def test_dsn
57
+ assert_respond_to(@dbrc, :dsn)
58
+ assert_respond_to(@dbrc, :dsn=)
59
+ end
60
+
61
+ def test_user
62
+ assert_respond_to(@dbrc, :user)
63
+ assert_respond_to(@dbrc, :user=)
64
+ assert_kind_of(String, @dbrc.user)
65
+ end
66
+
67
+ def test_password
68
+ assert_respond_to(@dbrc, :password)
69
+ assert_respond_to(@dbrc, :password=)
70
+ assert_respond_to(@dbrc, :passwd)
71
+ assert_respond_to(@dbrc, :passwd=)
72
+ assert_kind_of(String, @dbrc.password)
73
+ end
74
+
75
+ def test_driver
76
+ assert_respond_to(@dbrc, :driver)
77
+ assert_respond_to(@dbrc, :driver=)
78
+ assert_kind_of(String, @dbrc.driver)
79
+ end
80
+
81
+ def test_interval
82
+ assert_respond_to(@dbrc, :interval)
83
+ assert_respond_to(@dbrc, :interval=)
84
+ assert_kind_of(Fixnum, @dbrc.interval)
85
+ end
86
+
87
+ def test_timeout
88
+ assert_respond_to(@dbrc, :timeout)
89
+ assert_respond_to(@dbrc, :timeout=)
90
+ assert_respond_to(@dbrc, :time_out)
91
+ assert_respond_to(@dbrc, :time_out=)
92
+ assert_kind_of(Fixnum, @dbrc.timeout)
93
+ end
94
+
95
+ def test_max_reconn
96
+ assert_respond_to(@dbrc, :max_reconn)
97
+ assert_respond_to(@dbrc, :max_reconn=)
98
+ assert_respond_to(@dbrc, :maximum_reconnects)
99
+ assert_respond_to(@dbrc, :maximum_reconnects=)
100
+ assert_kind_of(Fixnum, @dbrc.maximum_reconnects)
101
+ end
102
+
103
+ def test_sample_values
104
+ assert_equal("foo", @dbrc.database)
105
+ assert_equal("user1", @dbrc.user)
106
+ assert_equal("pwd1", @dbrc.passwd)
107
+ assert_equal("Oracle", @dbrc.driver)
108
+ assert_equal(60, @dbrc.interval)
109
+ assert_equal(40, @dbrc.timeout)
110
+ assert_equal(3, @dbrc.max_reconn)
111
+ assert_equal("dbi:Oracle:foo", @dbrc.dsn)
112
+ end
113
+
114
+ # Same database, different user
115
+ def test_duplicate_database
116
+ db = DBRC::XML.new("foo", "user2", @dir)
117
+ assert_equal("user2", db.user)
118
+ assert_equal("pwd2", db.passwd)
119
+ assert_equal("OCI8", db.driver)
120
+ assert_equal(60, db.interval)
121
+ assert_equal(60, db.timeout)
122
+ assert_equal(4, db.max_reconn)
123
+ assert_equal("dbi:OCI8:foo", db.dsn)
124
+ end
125
+
126
+ # Different database, different user
127
+ def test_different_database
128
+ db = DBRC::XML.new("bar", "user1", @dir)
129
+ assert_equal("user1", db.user)
130
+ assert_equal("pwd3", db.passwd)
131
+ assert_equal("Oracle", db.driver)
132
+ assert_equal(30, db.interval)
133
+ assert_equal(30, db.timeout)
134
+ assert_equal(2, db.max_reconn)
135
+ assert_equal("dbi:Oracle:bar", db.dsn)
136
+ end
137
+
138
+ # A database with only a couple fields defined
139
+ def test_nil_values
140
+ db = DBRC::XML.new("baz", "user3", @dir)
141
+ assert_equal("user3", db.user)
142
+ assert_equal("pwd4", db.passwd)
143
+ assert_nil(db.driver)
144
+ assert_nil(db.interval)
145
+ assert_nil(db.timeout)
146
+ assert_nil(db.max_reconn)
147
+ assert_nil(db.dsn)
148
+ end
149
+
150
+ def teardown
151
+ @dir = nil
152
+ @db1 = nil
153
+ @db2 = nil
154
+ @user1 = nil
155
+ @user2 = nil
156
+ @db_bad = nil
157
+ @user_bad = nil
158
+ @dbrc = nil
159
+ end
160
+ end
@@ -0,0 +1,165 @@
1
+ #########################################################################
2
+ # tc_dbrc_yml.rb
3
+ #
4
+ # Test suite for the YAML specific version of DBI::DBRC. You should run
5
+ # this test case via the 'rake test' task.
6
+ #########################################################################
7
+ require "dbi/dbrc"
8
+ require "test/unit"
9
+ include DBI
10
+
11
+ class TC_DBRC_YML < Test::Unit::TestCase
12
+ def setup
13
+ Dir.chdir('test') if File.basename(Dir.pwd) != 'test'
14
+
15
+ @dir = "../examples/yml"
16
+ @file = File.join(@dir, '.dbrc')
17
+ @db1 = "foo"
18
+ @db2 = "bar"
19
+ @user1 = "user1"
20
+ @user2 = "user2"
21
+ @db_bad = "blah" # Doesn't exist
22
+ @user_bad = "user8" # Doesn't exist
23
+
24
+ if File::ALT_SEPARATOR
25
+ File.set_attr(@file, File::HIDDEN)
26
+ else
27
+ File.chmod(0600, @file)
28
+ end
29
+
30
+ @dbrc = DBRC::YML.new(@db1, nil, @dir)
31
+ end
32
+
33
+ def test_constructor
34
+ assert_raises(ArgumentError){ DBRC::YML.new }
35
+ assert_nothing_raised{ DBRC::YML.new(@db1, @user1, @dir) }
36
+ assert_nothing_raised{ DBRC::YML.new(@db1, nil, @dir) }
37
+ end
38
+
39
+ def test_bad_database
40
+ assert_raises(DBRC::Error){ DBRC::YML.new(@db_bad, nil, @dir) }
41
+ end
42
+
43
+ def test_bad_user
44
+ assert_raises(DBRC::Error){ DBRC::YML.new(@db1, @user_bad, @dir) }
45
+ end
46
+
47
+ def test_database
48
+ assert_respond_to(@dbrc, :database)
49
+ assert_respond_to(@dbrc, :database=)
50
+ assert_respond_to(@dbrc, :db)
51
+ assert_respond_to(@dbrc, :db=)
52
+ assert_kind_of(String, @dbrc.db)
53
+ end
54
+
55
+ def test_dsn
56
+ assert_respond_to(@dbrc, :dsn)
57
+ assert_respond_to(@dbrc, :dsn=)
58
+ end
59
+
60
+ def test_user
61
+ assert_respond_to(@dbrc, :user)
62
+ assert_respond_to(@dbrc, :user=)
63
+ assert_kind_of(String, @dbrc.user)
64
+ end
65
+
66
+ def test_password
67
+ assert_respond_to(@dbrc, :password)
68
+ assert_respond_to(@dbrc, :password=)
69
+ assert_respond_to(@dbrc, :passwd)
70
+ assert_respond_to(@dbrc, :passwd=)
71
+ assert_kind_of(String, @dbrc.password)
72
+ end
73
+
74
+ def test_driver
75
+ assert_respond_to(@dbrc, :driver)
76
+ assert_respond_to(@dbrc, :driver=)
77
+ assert_kind_of(String, @dbrc.driver)
78
+ end
79
+
80
+ def test_interval
81
+ assert_respond_to(@dbrc, :interval)
82
+ assert_respond_to(@dbrc, :interval=)
83
+ assert_kind_of(Fixnum, @dbrc.interval)
84
+ end
85
+
86
+ def test_timeout
87
+ assert_respond_to(@dbrc, :timeout)
88
+ assert_respond_to(@dbrc, :timeout=)
89
+ assert_respond_to(@dbrc, :time_out)
90
+ assert_respond_to(@dbrc, :time_out=)
91
+ assert_kind_of(Fixnum, @dbrc.timeout)
92
+ end
93
+
94
+ def test_max_reconn
95
+ assert_respond_to(@dbrc, :max_reconn)
96
+ assert_respond_to(@dbrc, :max_reconn=)
97
+ assert_respond_to(@dbrc, :maximum_reconnects)
98
+ assert_respond_to(@dbrc, :maximum_reconnects=)
99
+ assert_kind_of(Fixnum, @dbrc.maximum_reconnects)
100
+ end
101
+
102
+ def test_sample_values
103
+ assert_equal("foo", @dbrc.database)
104
+ assert_equal("user1", @dbrc.user)
105
+ assert_equal("pwd1", @dbrc.passwd)
106
+ assert_equal("Oracle", @dbrc.driver)
107
+ assert_equal(60, @dbrc.interval)
108
+ assert_equal(40, @dbrc.timeout)
109
+ assert_equal(3, @dbrc.max_reconn)
110
+ assert_equal("dbi:Oracle:foo", @dbrc.dsn)
111
+ end
112
+
113
+ # Same database, different user
114
+ def test_duplicate_database
115
+ db = DBRC::YML.new("foo", "user2", @dir)
116
+ assert_equal("user2", db.user)
117
+ assert_equal("pwd2", db.passwd)
118
+ assert_equal("OCI8", db.driver)
119
+ assert_equal(60, db.interval)
120
+ assert_equal(60, db.timeout)
121
+ assert_equal(4, db.max_reconn)
122
+ assert_equal("dbi:OCI8:foo", db.dsn)
123
+ end
124
+
125
+ # Different database, different user
126
+ def test_different_database
127
+ db = DBRC::YML.new("bar", "user1", @dir)
128
+ assert_equal("user1", db.user)
129
+ assert_equal("pwd3", db.passwd)
130
+ assert_equal("Oracle", db.driver)
131
+ assert_equal(30, db.interval)
132
+ assert_equal(30, db.timeout)
133
+ assert_equal(2, db.max_reconn)
134
+ assert_equal("dbi:Oracle:bar", db.dsn)
135
+ end
136
+
137
+ # A database with only a couple fields defined
138
+ def test_nil_values
139
+ db = DBRC::YML.new("baz", "user3", @dir)
140
+ assert_equal("user3", db.user)
141
+ assert_equal("pwd4", db.passwd)
142
+ assert_nil(db.driver)
143
+ assert_nil(db.interval)
144
+ assert_nil(db.timeout)
145
+ assert_nil(db.max_reconn)
146
+ assert_nil(db.dsn)
147
+ end
148
+
149
+ def teardown
150
+ @dir = nil
151
+ @db1 = nil
152
+ @db2 = nil
153
+ @user1 = nil
154
+ @user2 = nil
155
+ @db_bad = nil
156
+ @user_bad = nil
157
+ @dbrc = nil
158
+
159
+ if File::ALT_SEPARATOR
160
+ File.set_attr(@file, File::HIDDEN)
161
+ else
162
+ File.chmod(0600, @file)
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(Dir.pwd)
2
+ $LOAD_PATH.unshift(Dir.pwd + "/test")
3
+
4
+ require "tc_dbrc"
5
+ require "tc_dbrc_yml"
6
+ require "tc_dbrc_xml"
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dbi-dbrc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.2
5
+ platform: x86-mswin32-60
6
+ authors:
7
+ - Daniel Berger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-18 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sys-admin
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: win32-file
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: win32-dir
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.3.0
44
+ version:
45
+ description: A simple way to avoid hard-coding passwords with DBI
46
+ email: djberg96@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README
53
+ - CHANGES
54
+ - MANIFEST
55
+ files:
56
+ - examples/plain
57
+ - examples/plain/test.rb
58
+ - examples/xml
59
+ - examples/xml/test_xml.rb
60
+ - examples/yml
61
+ - examples/yml/test_yml.rb
62
+ - lib/dbi
63
+ - lib/dbi/dbrc.rb
64
+ - test/tc_dbrc.rb
65
+ - test/tc_dbrc_xml.rb
66
+ - test/tc_dbrc_yml.rb
67
+ - test/ts_all.rb
68
+ - README
69
+ - CHANGES
70
+ - MANIFEST
71
+ has_rdoc: true
72
+ homepage: http://www.rubyforge.org/projects/shards
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ requirements: []
91
+
92
+ rubyforge_project: shards
93
+ rubygems_version: 1.2.0
94
+ signing_key:
95
+ specification_version: 2
96
+ summary: A simple way to avoid hard-coding passwords with DBI
97
+ test_files:
98
+ - test/ts_all.rb