dbi-dbrc 1.1.6 → 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/CHANGES +7 -0
  2. data/README +3 -4
  3. data/Rakefile +26 -19
  4. data/dbi-dbrc.gemspec +37 -41
  5. data/lib/dbi/dbrc.rb +285 -282
  6. data/test/test_dbi_dbrc.rb +1 -1
  7. metadata +44 -22
data/CHANGES CHANGED
@@ -1,3 +1,10 @@
1
+ == 1.1.7 - 6-Oct-2010
2
+ * More robust file decryption/encryption for MS Windows.
3
+ * Better platform checking for MS Windows.
4
+ * Refactored the Rakefile. Removed the old installation tasks and replaced
5
+ them with a series of gem tasks.
6
+ * Updated the win32 library dependencies.
7
+
1
8
  == 1.1.6 - 10-Sep-2009
2
9
  * Fixed validation for dbrc_dir argument.
3
10
  * Added a test for bogus dbrc_dir arguments.
data/README CHANGED
@@ -10,6 +10,9 @@
10
10
  * win32-file (MS Windows only)
11
11
  * win32-dir (MS Windows only)
12
12
 
13
+ == Installation
14
+ gem install dbi-dbrc
15
+
13
16
  == Synopsis
14
17
  require 'dbi/dbrc'
15
18
  include DBI
@@ -28,10 +31,6 @@
28
31
  puts dbrc.interval
29
32
  puts dbrc.dsn
30
33
 
31
- == Installation
32
- rake test (optional)
33
- rake install (non-gem) or rake install_gem (gem)
34
-
35
34
  == Notes on the .dbrc file
36
35
  This module relies on a file in your home directory called ".dbrc", and it
37
36
  is meant to be analogous to the ".netrc" file used by programs such as
data/Rakefile CHANGED
@@ -1,33 +1,40 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
 
4
- desc "Install the dbi-dbrc package (non-gem)"
5
- task :install do
6
- dest = File.join(Config::CONFIG['sitelibdir'], 'dbi')
7
- Dir.mkdir(dest) unless File.exists? dest
8
- cp 'lib/dbi/dbrc.rb', dest, :verbose => true
9
- end
4
+ namespace :gem do
5
+ desc "Remove any gem files."
6
+ task :clean do
7
+ Dir['*.gem'].each{ |f| File.delete(f) }
8
+ end
9
+
10
+ desc "Create the dbi-dbrc gem"
11
+ task :create => [:clean] do
12
+ spec = eval(IO.read('dbi-dbrc.gemspec'))
13
+ Gem::Builder.new(spec).build
14
+ end
10
15
 
11
- desc "Install the dbi-dbrc package as a gem"
12
- task :install_gem do
13
- ruby 'dbi-dbrc.gemspec'
14
- file = Dir["*.gem"].first
15
- sh "gem install #{file}"
16
+ desc "Install the dbi-dbrc gem"
17
+ task :install => [:build] do
18
+ gem = Dir["*.gem"].first
19
+ sh "gem install #{gem}"
20
+ end
16
21
  end
17
22
 
18
23
  Rake::TestTask.new do |t|
19
- t.warning = true
20
- t.verbose = true
24
+ t.warning = true
25
+ t.verbose = true
21
26
  end
22
27
 
23
28
  Rake::TestTask.new(:test_xml) do |t|
24
- t.warning = true
25
- t.verbose = true
26
- t.test_files = FileList['test/test_dbi_dbrc_xml.rb']
29
+ t.warning = true
30
+ t.verbose = true
31
+ t.test_files = FileList['test/test_dbi_dbrc_xml.rb']
27
32
  end
28
33
 
29
34
  Rake::TestTask.new(:test_yml) do |t|
30
- t.warning = true
31
- t.verbose = true
32
- t.test_files = FileList['test/test_dbi_dbrc_yml.rb']
35
+ t.warning = true
36
+ t.verbose = true
37
+ t.test_files = FileList['test/test_dbi_dbrc_yml.rb']
33
38
  end
39
+
40
+ task :default => :test
@@ -1,41 +1,37 @@
1
- require 'rubygems'
2
-
3
- spec = Gem::Specification.new do |s|
4
- s.name = 'dbi-dbrc'
5
- s.version = '1.1.6'
6
- s.author = 'Daniel Berger'
7
- s.email = 'djberg96@gmail.com'
8
- s.license = 'Artistic 2.0'
9
- s.summary = 'A simple way to avoid hard-coding passwords with DBI'
10
- s.homepage = 'http://www.rubyforge.org/projects/shards'
11
- s.platform = Gem::Platform::RUBY
12
- s.files = Dir['**/*'].reject{ |f| f.include?('CVS') }
13
- s.test_files = Dir['test/test*.rb']
14
- s.has_rdoc = true
15
-
16
- s.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
17
- s.rubyforge_project = 'shards'
18
-
19
- s.add_dependency('sys-admin', '>= 1.5.2')
20
- s.add_development_dependency('test-unit')
21
-
22
- if Config::CONFIG['host_os'] =~ /mswin|win32|dos/i
23
- s.add_dependency('win32-file', '>= 0.4.2')
24
- s.add_dependency('win32-dir', '>= 0.3.0')
25
- s.add_dependency('win32-process', '>= 0.6.1')
26
- s.platform = Gem::Platform::CURRENT
27
- end
28
-
29
- s.description = <<-EOF
30
- The dbi-dbrc library provides an interface for storing database
31
- connection information, including passwords, in a locally secure
32
- file only accessible by you, or root. This allows you to avoid
33
- hard coding login and password information in your programs
34
- that require such information.
35
-
36
- This library can also be used to store login and password information
37
- for logins on remote hosts, not just databases.
38
- EOF
39
- end
40
-
41
- Gem::Builder.new(spec).build
1
+ require 'rubygems'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'dbi-dbrc'
5
+ spec.version = '1.1.7'
6
+ spec.author = 'Daniel Berger'
7
+ spec.email = 'djberg96@gmail.com'
8
+ spec.license = 'Artistic 2.0'
9
+ spec.summary = 'A simple way to avoid hard-coding passwords with DBI'
10
+ spec.homepage = 'http://www.rubyforge.org/projects/shards'
11
+ spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
12
+ spec.test_files = Dir['test/test*.rb']
13
+
14
+ spec.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
15
+ spec.rubyforge_project = 'shards'
16
+
17
+ spec.add_dependency('sys-admin', '>= 1.5.2')
18
+ spec.add_development_dependency('test-unit')
19
+
20
+ if Config::CONFIG['host_os'] =~ /mswin|msdos|win32|mingw|cygwin/i
21
+ spec.add_dependency('win32-file', '>= 0.6.6')
22
+ spec.add_dependency('win32-dir', '>= 0.3.7')
23
+ spec.add_dependency('win32-process', '>= 0.6.2')
24
+ spec.platform = Gem::Platform::CURRENT
25
+ end
26
+
27
+ spec.description = <<-EOF
28
+ The dbi-dbrc library provides an interface for storing database
29
+ connection information, including passwords, in a locally secure
30
+ file only accessible by you, or root. This allows you to avoid
31
+ hard coding login and password information in your programs
32
+ that require such information.
33
+
34
+ This library can also be used to store login and password information
35
+ for logins on remote hosts, not just databases.
36
+ EOF
37
+ end
@@ -1,9 +1,10 @@
1
1
  require 'rbconfig'
2
+ require 'rubygems'
2
3
 
3
- if Config::CONFIG['host_os'] =~ /mswin|win32|dos/i
4
- require 'win32/file'
5
- require 'win32/dir'
6
- require 'win32/process'
4
+ if Config::CONFIG['host_os'] =~ /mswin|msdos|win32|mingw|cygwin/i
5
+ require 'win32/dir'
6
+ require 'win32/file'
7
+ require 'win32/process'
7
8
  end
8
9
 
9
10
  require 'sys/admin'
@@ -11,292 +12,294 @@ require 'sys/admin'
11
12
  # The DBI module serves as a namespace only.
12
13
  module DBI
13
14
 
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
- class Error < StandardError; end
19
-
20
- # The version of the dbi-dbrc library
21
- VERSION = '1.1.6'
22
-
23
- @@windows = Config::CONFIG['host_os'] =~ /mswin|win32|dos/i
24
-
25
- # The database or host to be connected to.
26
- attr_accessor :database
27
-
28
- # The user name used for the database or host connection.
29
- attr_accessor :user
30
-
31
- # The password associated with the database or host.
32
- attr_accessor :password
33
-
34
- # The driver associated with the database. This is used to internally to
35
- # construct the DSN.
36
- attr_accessor :driver
37
-
38
- # Data source name, e.g. "dbi:OCI8:your_database".
39
- attr_accessor :dsn
40
-
41
- # The maximum number of reconnects a program should make before
42
- # giving up.
43
- attr_accessor :maximum_reconnects
44
-
45
- # The timeout, in seconds, for each connection attempt.
46
- attr_accessor :timeout
47
-
48
- # The interval, in seconds, between each connection attempt.
49
- attr_accessor :interval
50
-
51
- # The directory where the .dbrc file is stored.
52
- attr_accessor :dbrc_dir
53
-
54
- # The full path to the .dbrc file.
55
- attr_accessor :dbrc_file
56
-
57
- # Returns a new DBI::DBRC object. The contents of the object depend on
58
- # the arguments passed to the constructor. If only a database name is
59
- # passed, then the first entry found in the .dbrc file that matches that
60
- # database is parsed. If a user name is also included, then the first
61
- # entry that matches both the database and user name is parsed.
62
- #
63
- # If a directory is passed as the third argument, then DBRC will look
64
- # in that directory, instead of the default directory, for the .dbrc
65
- # file.
66
- #
67
- # If an entry cannot be found for the database, or database plus user
68
- # combination, then a Error is raised. If the .dbrc file cannot
69
- # be found, or is setup improperly with regards to permissions or
70
- # properties, a DBI::DBRC::Error is raised.
71
- #
72
- # See the README for the rules regarding .dbrc files and permissions.
73
- #
74
- # Note that this library can also be used as a general password
75
- # storage mechanism. In that case simply treat the 'database' as the
76
- # host name, and ignore the DBI::DBRC#dsn and DBI::DBRC#driver methods.
77
- #
78
- # Examples:
79
- #
80
- # # Find the first match for 'some_database'
81
- # DBI::DBRC.new('some_database')
82
- #
83
- # # Find the first match for 'foo_user@some_database'
84
- # DBI::DBRC.new('some_database', 'foo_user')
85
- #
86
- # # Find the first match for 'foo_user@some_database' under /usr/local
87
- # DBI::DBRC.new('some_database', 'foo_usr', '/usr/local')
88
- #
89
- def initialize(database, user=nil, dbrc_dir=nil)
90
- if dbrc_dir.nil?
91
- uid = Process.uid
92
- home = ENV['HOME'] || ENV['USERPROFILE']
93
-
94
- if home.nil?
95
- if @@windows
96
- home ||= Sys::Admin.get_user(uid, :localaccount => true).dir
97
- else
98
- home ||= Sys::Admin.get_user(uid).dir
99
- end
100
- end
101
-
102
- # Default to the app data directory on Windows if no home dir found
103
- if @@windows && home.nil?
104
- @dbrc_file = File.join(File.basename(Dir::APPDATA), '.dbrc')
105
- else
106
- uid = Process.uid
107
- @dbrc_file = File.join(Sys::Admin.get_user(uid).dir, '.dbrc')
108
- end
109
- else
110
- raise Error, 'bad directory' unless File.directory?(dbrc_dir)
111
- @dbrc_file = File.join(dbrc_dir, '.dbrc')
112
- end
15
+ # The DBRC class encapsulates a database resource config file.
16
+ class DBRC
17
+
18
+ # This error is raised if anything fails trying to read the config file.
19
+ class Error < StandardError; end
20
+
21
+ # The version of the dbi-dbrc library
22
+ VERSION = '1.1.7'
23
+
24
+ @@windows = Config::CONFIG['host_os'] =~ /mswin|msdos|win32|mingw|cygwin/i
25
+
26
+ # The database or host to be connected to.
27
+ attr_accessor :database
28
+
29
+ # The user name used for the database or host connection.
30
+ attr_accessor :user
31
+
32
+ # The password associated with the database or host.
33
+ attr_accessor :password
34
+
35
+ # The driver associated with the database. This is used to internally to
36
+ # construct the DSN.
37
+ attr_accessor :driver
38
+
39
+ # Data source name, e.g. "dbi:OCI8:your_database".
40
+ attr_accessor :dsn
41
+
42
+ # The maximum number of reconnects a program should make before giving up.
43
+ attr_accessor :maximum_reconnects
44
+
45
+ # The timeout, in seconds, for each connection attempt.
46
+ attr_accessor :timeout
47
+
48
+ # The interval, in seconds, between each connection attempt.
49
+ attr_accessor :interval
50
+
51
+ # The directory where the .dbrc file is stored.
52
+ attr_accessor :dbrc_dir
53
+
54
+ # The full path to the .dbrc file.
55
+ attr_accessor :dbrc_file
56
+
57
+ # Returns a new DBI::DBRC object. The contents of the object depend on
58
+ # the arguments passed to the constructor. If only a database name is
59
+ # passed, then the first entry found in the .dbrc file that matches that
60
+ # database is parsed. If a user name is also included, then the first
61
+ # entry that matches both the database and user name is parsed.
62
+ #
63
+ # If a directory is passed as the third argument, then DBRC will look
64
+ # in that directory, instead of the default directory, for the .dbrc
65
+ # file.
66
+ #
67
+ # If an entry cannot be found for the database, or database plus user
68
+ # combination, then a Error is raised. If the .dbrc file cannot be
69
+ # found, or is setup improperly with regards to permissions or properties
70
+ # then a DBI::DBRC::Error is raised.
71
+ #
72
+ # See the README for the rules regarding .dbrc files and permissions.
73
+ #
74
+ # Note that this library can also be used as a general password
75
+ # storage mechanism. In that case simply treat the 'database' as the
76
+ # host name, and ignore the DBI::DBRC#dsn and DBI::DBRC#driver methods.
77
+ #
78
+ # Examples:
79
+ #
80
+ # # Find the first match for 'some_database'
81
+ # DBI::DBRC.new('some_database')
82
+ #
83
+ # # Find the first match for 'foo_user@some_database'
84
+ # DBI::DBRC.new('some_database', 'foo_user')
85
+ #
86
+ # # Find the first match for 'foo_user@some_database' under /usr/local
87
+ # DBI::DBRC.new('some_database', 'foo_usr', '/usr/local')
88
+ #
89
+ def initialize(database, user=nil, dbrc_dir=nil)
90
+ if dbrc_dir.nil?
91
+ uid = Process.uid
92
+ home = ENV['HOME'] || ENV['USERPROFILE']
93
+
94
+ if home.nil?
95
+ if @@windows
96
+ home ||= Sys::Admin.get_user(uid, :localaccount => true).dir
97
+ else
98
+ home ||= Sys::Admin.get_user(uid).dir
99
+ end
100
+ end
101
+
102
+ # Default to the app data directory on Windows if no home dir found
103
+ if @@windows && home.nil?
104
+ @dbrc_file = File.join(File.basename(Dir::APPDATA), '.dbrc')
105
+ else
106
+ uid = Process.uid
107
+ @dbrc_file = File.join(Sys::Admin.get_user(uid).dir, '.dbrc')
108
+ end
109
+ else
110
+ raise Error, 'bad directory' unless File.directory?(dbrc_dir)
111
+ @dbrc_file = File.join(dbrc_dir, '.dbrc')
112
+ end
113
113
 
114
- @dbrc_dir = dbrc_dir
115
- @database = database
116
- @user = user
117
- encrypted = false # Win32 only
114
+ @dbrc_dir = dbrc_dir
115
+ @database = database
116
+ @user = user
117
+ encrypted = false # Win32 only
118
118
 
119
- @driver = nil
120
- @interval = nil
121
- @timeout = nil
122
- @maximum_reconnects = nil
119
+ @driver = nil
120
+ @interval = nil
121
+ @timeout = nil
122
+ @maximum_reconnects = nil
123
123
 
124
- check_file()
125
-
126
- # If on Win32 and the file is encrypted, decrypt it.
127
- if @@windows && File.encrypted?(@dbrc_file)
128
- encrypted = true
129
- File.decrypt(@dbrc_file)
130
- end
124
+ check_file()
131
125
 
132
- parse_dbrc_config_file()
133
- validate_data()
134
- convert_numeric_strings()
135
- create_dsn_string()
126
+ # Decrypt and re-encrypt the file if we're on MS Windows and the
127
+ # file is encrypted.
128
+ begin
129
+ if @@windows && File.encrypted?(@dbrc_file)
130
+ file_was_encrypted = true
131
+ File.decrypt(@dbrc_file)
132
+ end
136
133
 
137
- # If on Win32 and the file was encrypted, re-encrypt it
138
- if @@windows && encrypted
139
- File.encrypt(@dbrc_file)
140
- end
134
+ parse_dbrc_config_file()
135
+ validate_data()
136
+ convert_numeric_strings()
137
+ create_dsn_string()
138
+ ensure
139
+ if @@windows && file_was_encrypted
140
+ File.encrypt(@dbrc_file)
141
+ end
141
142
  end
142
-
143
- # Inspection of the DBI::DBRC object. This is identical to the standard
144
- # Ruby Object#inspect, except that the password field is filtered.
145
- #
146
- def inspect
147
- str = instance_variables.map{ |iv|
148
- if iv == '@password'
149
- "#{iv}=[FILTERED]"
150
- else
151
- "#{iv}=#{instance_variable_get(iv).inspect}"
152
- end
153
- }.join(', ')
154
-
155
- "#<#{self.class}:0x#{(self.object_id*2).to_s(16)} " << str << ">"
143
+ end
144
+
145
+ # Inspection of the DBI::DBRC object. This is identical to the standard
146
+ # Ruby Object#inspect, except that the password field is filtered.
147
+ #
148
+ def inspect
149
+ str = instance_variables.map{ |iv|
150
+ if iv == '@password'
151
+ "#{iv}=[FILTERED]"
152
+ else
153
+ "#{iv}=#{instance_variable_get(iv).inspect}"
154
+ end
155
+ }.join(', ')
156
+
157
+ "#<#{self.class}:0x#{(self.object_id*2).to_s(16)} " << str << ">"
158
+ end
159
+
160
+ private
161
+
162
+ # Ensure that the user/password has been set
163
+ def validate_data
164
+ unless @user
165
+ raise Error, "no user found associated with #{@database}"
156
166
  end
157
167
 
158
- private
159
-
160
- # Ensure that the user/password has been set
161
- def validate_data
162
- unless @user
163
- raise Error, "no user found associated with #{@database}"
164
- end
165
-
166
- unless @password
167
- raise Error, "password not defined for #{@user}@#{@database}"
168
- end
168
+ unless @password
169
+ raise Error, "password not defined for #{@user}@#{@database}"
169
170
  end
171
+ end
170
172
 
171
- # Converts strings that should be numbers into actual numbers
172
- def convert_numeric_strings
173
- @interval = @interval.to_i if @interval
174
- @timeout = @timeout.to_i if @timeout
175
- @maximum_reconnects = @maximum_reconnects.to_i if @maximum_reconnects
176
- end
177
-
178
- # Create the dsn string if the driver is defined
179
- def create_dsn_string
180
- @dsn = "dbi:#{@driver}:#{@database}" if @driver
181
- end
182
-
183
- # Check ownership and permissions
184
- def check_file(file=@dbrc_file)
185
- File.open(file){ |f|
186
-
187
- # Permissions must be set to 600 or better on Unix systems.
188
- # Must be hidden on Win32 systems.
189
- if @@windows
190
- unless File.hidden?(file)
191
- raise Error, "The .dbrc file must be hidden"
192
- end
193
- else
194
- unless (f.stat.mode & 077) == 0
195
- raise Error, "Bad .dbrc file permissions"
196
- end
197
- end
198
-
199
- # Only the owner may use it
200
- unless f.stat.owned?
201
- raise Error, "Not owner of .dbrc file"
202
- end
203
- }
204
- end
205
-
206
- # Parse the text out of the .dbrc file. This is the only method you
207
- # need to redefine if writing your own config handler.
208
- def parse_dbrc_config_file(file=@dbrc_file)
209
- IO.foreach(file){ |line|
210
- next if line =~ /^#/ # Ignore comments
211
- db, user, pwd, driver, timeout, max, interval = line.split
212
-
213
- next unless @database == db
214
-
215
- if @user
216
- next unless @user == user
217
- end
218
-
219
- @user = user
220
- @password = pwd
221
- @driver = driver
222
- @timeout = timeout
223
- @maximum_reconnects = max
224
- @interval = interval
225
- return
226
- }
227
-
228
- # If we reach here it means the database and/or user wasn't found
229
- if @user
230
- err = "no record found for #{@user}@#{@database}"
231
- else
232
- err = "no record found for #{@database}"
233
- end
234
-
235
- raise Error, err
236
- end
237
-
238
- alias_method(:db, :database)
239
- alias_method(:db=, :database=)
240
- alias_method(:passwd, :password)
241
- alias_method(:passwd=, :password=)
242
- alias_method(:max_reconn, :maximum_reconnects)
243
- alias_method(:max_reconn=, :maximum_reconnects=)
244
- alias_method(:time_out, :timeout)
245
- alias_method(:time_out=, :timeout=)
246
- alias_method(:host, :database)
247
- end
248
-
249
- # A subclass of DBRC designed to handle .dbrc files in XML format. The
250
- # public methods of this class are identical to DBRC.
251
- class XML < DBRC
252
- require "rexml/document"
253
- include REXML
254
- private
255
- def parse_dbrc_config_file(file=@dbrc_file)
256
- doc = Document.new(File.new(file))
257
- fields = %w/user password driver interval timeout maximum_reconnects/
258
- doc.elements.each("/dbrc/database"){ |element|
259
- next unless element.attributes["name"] == database
260
- if @user
261
- next unless element.elements["user"].text == @user
262
- end
263
- fields.each{ |field|
264
- val = element.elements[field]
265
- unless val.nil?
266
- send("#{field}=",val.text)
267
- end
268
- }
269
- return
270
- }
271
- # If we reach here it means the database and/or user wasn't found
272
- raise Error, "No record found for #{@user}@#{@database}"
273
- end
274
- end
275
-
276
- # A subclass of DBRC designed to handle .dbrc files in YAML format. The
277
- # public methods of this class are identical to DBRC.
278
- class YML < DBRC
279
- require "yaml"
280
- private
281
- def parse_dbrc_config_file(file=@dbrc_file)
282
- config = YAML.load(File.open(file))
283
- config.each{ |hash|
284
- hash.each{ |db,info|
285
- next unless db == @database
286
- if @user
287
- next unless @user == info["user"]
288
- end
289
- @user = info["user"]
290
- @password = info["password"]
291
- @driver = info["driver"]
292
- @interval = info["interval"]
293
- @timeout = info["timeout"]
294
- @maximum_reconnects = info["max_reconn"]
295
- return
296
- }
297
- }
298
- # If we reach this point, it means the database wasn't found
299
- raise Error, "No entry found for #{@user}@#{@database}"
300
- end
301
- end
173
+ # Converts strings that should be numbers into actual numbers
174
+ def convert_numeric_strings
175
+ @interval = @interval.to_i if @interval
176
+ @timeout = @timeout.to_i if @timeout
177
+ @maximum_reconnects = @maximum_reconnects.to_i if @maximum_reconnects
178
+ end
179
+
180
+ # Create the dsn string if the driver is defined
181
+ def create_dsn_string
182
+ @dsn = "dbi:#{@driver}:#{@database}" if @driver
183
+ end
184
+
185
+ # Check ownership and permissions
186
+ def check_file(file=@dbrc_file)
187
+ File.open(file){ |f|
188
+ # Permissions must be set to 600 or better on Unix systems.
189
+ # Must be hidden on Win32 systems.
190
+ if @@windows
191
+ unless File.hidden?(file)
192
+ raise Error, "The .dbrc file must be hidden"
193
+ end
194
+ else
195
+ unless (f.stat.mode & 077) == 0
196
+ raise Error, "Bad .dbrc file permissions"
197
+ end
198
+ end
199
+
200
+ # Only the owner may use it
201
+ unless f.stat.owned?
202
+ raise Error, "Not owner of .dbrc file"
203
+ end
204
+ }
205
+ end
206
+
207
+ # Parse the text out of the .dbrc file. This is the only method you
208
+ # need to redefine if writing your own config handler.
209
+ def parse_dbrc_config_file(file=@dbrc_file)
210
+ IO.foreach(file){ |line|
211
+ next if line =~ /^#/ # Ignore comments
212
+ db, user, pwd, driver, timeout, max, interval = line.split
213
+
214
+ next unless @database == db
215
+
216
+ if @user
217
+ next unless @user == user
218
+ end
219
+
220
+ @user = user
221
+ @password = pwd
222
+ @driver = driver
223
+ @timeout = timeout
224
+ @maximum_reconnects = max
225
+ @interval = interval
226
+ return
227
+ }
228
+
229
+ # If we reach here it means the database and/or user wasn't found
230
+ if @user
231
+ err = "no record found for #{@user}@#{@database}"
232
+ else
233
+ err = "no record found for #{@database}"
234
+ end
235
+
236
+ raise Error, err
237
+ end
238
+
239
+ alias_method(:db, :database)
240
+ alias_method(:db=, :database=)
241
+ alias_method(:passwd, :password)
242
+ alias_method(:passwd=, :password=)
243
+ alias_method(:max_reconn, :maximum_reconnects)
244
+ alias_method(:max_reconn=, :maximum_reconnects=)
245
+ alias_method(:time_out, :timeout)
246
+ alias_method(:time_out=, :timeout=)
247
+ alias_method(:host, :database)
248
+ end
249
+
250
+ # A subclass of DBRC designed to handle .dbrc files in XML format. The
251
+ # public methods of this class are identical to DBRC.
252
+ class XML < DBRC
253
+ require "rexml/document"
254
+ include REXML
255
+
256
+ private
257
+
258
+ def parse_dbrc_config_file(file=@dbrc_file)
259
+ doc = Document.new(File.new(file))
260
+ fields = %w/user password driver interval timeout maximum_reconnects/
261
+ doc.elements.each("/dbrc/database"){ |element|
262
+ next unless element.attributes["name"] == database
263
+ if @user
264
+ next unless element.elements["user"].text == @user
265
+ end
266
+ fields.each{ |field|
267
+ val = element.elements[field]
268
+ unless val.nil?
269
+ send("#{field}=",val.text)
270
+ end
271
+ }
272
+ return
273
+ }
274
+ # If we reach here it means the database and/or user wasn't found
275
+ raise Error, "No record found for #{@user}@#{@database}"
276
+ end
277
+ end
278
+
279
+ # A subclass of DBRC designed to handle .dbrc files in YAML format. The
280
+ # public methods of this class are identical to DBRC.
281
+ class YML < DBRC
282
+ require "yaml"
283
+
284
+ private
285
+
286
+ def parse_dbrc_config_file(file=@dbrc_file)
287
+ config = YAML.load(File.open(file))
288
+ config.each{ |hash|
289
+ hash.each{ |db,info|
290
+ next unless db == @database
291
+ next unless @user == info["user"] if @user
292
+ @user = info["user"]
293
+ @password = info["password"]
294
+ @driver = info["driver"]
295
+ @interval = info["interval"]
296
+ @timeout = info["timeout"]
297
+ @maximum_reconnects = info["max_reconn"]
298
+ return
299
+ }
300
+ }
301
+ # If we reach this point, it means the database wasn't found
302
+ raise Error, "No entry found for #{@user}@#{@database}"
303
+ end
304
+ end
302
305
  end
@@ -36,7 +36,7 @@ class TC_DBI_DBRC < Test::Unit::TestCase
36
36
  end
37
37
 
38
38
  def test_version
39
- assert_equal('1.1.6', DBRC::VERSION)
39
+ assert_equal('1.1.7', DBRC::VERSION)
40
40
  end
41
41
 
42
42
  def test_bad_dbrc_properties
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbi-dbrc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 7
10
+ version: 1.1.7
5
11
  platform: ruby
6
12
  authors:
7
13
  - Daniel Berger
@@ -9,30 +15,40 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-09-10 00:00:00 -06:00
18
+ date: 2010-10-06 00:00:00 -06:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: sys-admin
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 2
23
34
  version: 1.5.2
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: test-unit
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
33
48
  version: "0"
34
- version:
35
- description: " The dbi-dbrc library provides an interface for storing database\n connection information, including passwords, in a locally secure\n file only accessible by you, or root. This allows you to avoid\n hard coding login and password information in your programs\n that require such information.\n\n This library can also be used to store login and password information\n for logins on remote hosts, not just databases.\n"
49
+ type: :development
50
+ version_requirements: *id002
51
+ description: " The dbi-dbrc library provides an interface for storing database\n connection information, including passwords, in a locally secure\n file only accessible by you, or root. This allows you to avoid\n hard coding login and password information in your programs\n that require such information.\n\n This library can also be used to store login and password information\n for logins on remote hosts, not just databases.\n"
36
52
  email: djberg96@gmail.com
37
53
  executables: []
38
54
 
@@ -43,18 +59,18 @@ extra_rdoc_files:
43
59
  - CHANGES
44
60
  - MANIFEST
45
61
  files:
46
- - lib/dbi/dbrc.rb
47
- - examples/xml/test_xml.rb
48
- - examples/plain/test.rb
49
- - examples/yml/test_yml.rb
50
62
  - CHANGES
51
63
  - dbi-dbrc.gemspec
64
+ - examples/plain/test.rb
65
+ - examples/xml/test_xml.rb
66
+ - examples/yml/test_yml.rb
67
+ - lib/dbi/dbrc.rb
68
+ - MANIFEST
69
+ - Rakefile
52
70
  - README
53
- - test/test_dbi_dbrc_xml.rb
54
71
  - test/test_dbi_dbrc.rb
72
+ - test/test_dbi_dbrc_xml.rb
55
73
  - test/test_dbi_dbrc_yml.rb
56
- - MANIFEST
57
- - Rakefile
58
74
  has_rdoc: true
59
75
  homepage: http://www.rubyforge.org/projects/shards
60
76
  licenses:
@@ -65,25 +81,31 @@ rdoc_options: []
65
81
  require_paths:
66
82
  - lib
67
83
  required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
68
85
  requirements:
69
86
  - - ">="
70
87
  - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
71
91
  version: "0"
72
- version:
73
92
  required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
74
94
  requirements:
75
95
  - - ">="
76
96
  - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
77
100
  version: "0"
78
- version:
79
101
  requirements: []
80
102
 
81
103
  rubyforge_project: shards
82
- rubygems_version: 1.3.5
104
+ rubygems_version: 1.3.7
83
105
  signing_key:
84
106
  specification_version: 3
85
107
  summary: A simple way to avoid hard-coding passwords with DBI
86
108
  test_files:
87
- - test/test_dbi_dbrc_xml.rb
88
109
  - test/test_dbi_dbrc.rb
110
+ - test/test_dbi_dbrc_xml.rb
89
111
  - test/test_dbi_dbrc_yml.rb