dbi-dbrc 1.2.0 → 1.6.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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +4 -0
- data/{CHANGES → CHANGES.md} +56 -22
- data/Gemfile +3 -0
- data/{MANIFEST → MANIFEST.md} +7 -6
- data/README.md +292 -0
- data/Rakefile +9 -33
- data/certs/djberg96_pub.pem +26 -0
- data/dbi-dbrc.gemspec +17 -5
- data/examples/yml/test_yml.rb +5 -5
- data/lib/dbi-dbrc.rb +3 -0
- data/lib/dbi/dbrc.rb +115 -116
- data/spec/dbi_dbrc_spec.rb +247 -0
- data/spec/dbi_dbrc_xml_spec.rb +101 -0
- data/spec/dbi_dbrc_yml_spec.rb +95 -0
- data/spec/spec_helper.rb +6 -0
- metadata +88 -30
- metadata.gz.sig +0 -0
- data/README +0 -260
- data/test/test_dbi_dbrc.rb +0 -198
- data/test/test_dbi_dbrc_xml.rb +0 -159
- data/test/test_dbi_dbrc_yml.rb +0 -157
data/Rakefile
CHANGED
@@ -1,24 +1,16 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/clean'
|
3
|
-
require '
|
3
|
+
require 'rspec/core/rake_task'
|
4
4
|
|
5
|
-
CLEAN.include("**/*.gem", "**/*.rbc")
|
5
|
+
CLEAN.include("**/*.gem", "**/*.rbc", "**/*.lock")
|
6
6
|
|
7
7
|
namespace :gem do
|
8
|
-
desc "Remove any gem files."
|
9
|
-
task :clean do
|
10
|
-
Dir['*.gem'].each{ |f| File.delete(f) }
|
11
|
-
end
|
12
|
-
|
13
8
|
desc "Create the dbi-dbrc gem"
|
14
9
|
task :create => [:clean] do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
require 'rubygems/package'
|
20
|
-
Gem::Package.build(spec)
|
21
|
-
end
|
10
|
+
require 'rubygems/package'
|
11
|
+
spec = Gem::Specification.load('dbi-dbrc.gemspec')
|
12
|
+
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
13
|
+
Gem::Package.build(spec)
|
22
14
|
end
|
23
15
|
|
24
16
|
desc "Install the dbi-dbrc gem"
|
@@ -28,23 +20,7 @@ namespace :gem do
|
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
31
|
-
|
32
|
-
|
33
|
-
t.warning = true
|
34
|
-
t.verbose = true
|
35
|
-
end
|
36
|
-
|
37
|
-
Rake::TestTask.new(:xml) do |t|
|
38
|
-
t.warning = true
|
39
|
-
t.verbose = true
|
40
|
-
t.test_files = FileList['test/test_dbi_dbrc_xml.rb']
|
41
|
-
end
|
42
|
-
|
43
|
-
Rake::TestTask.new(:yml) do |t|
|
44
|
-
t.warning = true
|
45
|
-
t.verbose = true
|
46
|
-
t.test_files = FileList['test/test_dbi_dbrc_yml.rb']
|
47
|
-
end
|
48
|
-
end
|
23
|
+
desc "Run the test suite"
|
24
|
+
RSpec::Core::RakeTask.new(:spec)
|
49
25
|
|
50
|
-
task :default =>
|
26
|
+
task :default => :spec
|
@@ -0,0 +1,26 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
|
3
|
+
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
4
|
+
MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
|
5
|
+
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
6
|
+
bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
|
7
|
+
A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
|
8
|
+
u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
|
9
|
+
75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
|
10
|
+
6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
|
11
|
+
iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
|
12
|
+
ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
|
13
|
+
74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
|
14
|
+
058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
|
15
|
+
HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
|
16
|
+
AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
|
17
|
+
YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
|
18
|
+
/3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
|
19
|
+
h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
|
20
|
+
6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
|
21
|
+
ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
|
22
|
+
1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
|
23
|
+
DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
|
24
|
+
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
25
|
+
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
26
|
+
-----END CERTIFICATE-----
|
data/dbi-dbrc.gemspec
CHANGED
@@ -2,21 +2,33 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'dbi-dbrc'
|
5
|
-
spec.version = '1.
|
5
|
+
spec.version = '1.6.0'
|
6
6
|
spec.author = 'Daniel Berger'
|
7
7
|
spec.email = 'djberg96@gmail.com'
|
8
|
-
spec.license = '
|
8
|
+
spec.license = 'Apache-2.0'
|
9
9
|
spec.summary = 'A simple way to avoid hard-coding passwords with DBI'
|
10
10
|
spec.homepage = 'https://github.com/djberg96/dbi-dbrc'
|
11
11
|
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
12
12
|
spec.test_files = Dir['test/test*.rb']
|
13
|
+
spec.cert_chain = Dir['certs/*']
|
13
14
|
|
14
|
-
spec.
|
15
|
+
spec.add_dependency('gpgme', '~> 2.0')
|
15
16
|
|
16
|
-
spec.
|
17
|
-
spec.add_development_dependency('
|
17
|
+
spec.add_development_dependency('rake')
|
18
|
+
spec.add_development_dependency('rspec', '~> 3.9')
|
19
|
+
spec.add_development_dependency('fakefs', '~> 1.3')
|
20
|
+
|
21
|
+
spec.metadata = {
|
22
|
+
'homepage_uri' => 'https://github.com/djberg96/dbi-dbrc',
|
23
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/dbi-dbrc/issues',
|
24
|
+
'changelog_uri' => 'https://github.com/djberg96/dbi-dbrc/blob/main/CHANGES.md',
|
25
|
+
'documentation_uri' => 'https://github.com/djberg96/dbi-dbrc/wiki',
|
26
|
+
'source_code_uri' => 'https://github.com/djberg96/dbi-dbrc',
|
27
|
+
'wiki_uri' => 'https://github.com/djberg96/dbi-dbrc/wiki'
|
28
|
+
}
|
18
29
|
|
19
30
|
if File::ALT_SEPARATOR
|
31
|
+
spec.add_dependency('sys-admin')
|
20
32
|
spec.add_dependency('win32-file-attributes')
|
21
33
|
spec.add_dependency('win32-dir')
|
22
34
|
spec.add_dependency('win32-process')
|
data/examples/yml/test_yml.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
#######################################################################
|
2
|
-
#
|
2
|
+
# test_yml.rb
|
3
3
|
#
|
4
|
-
# Simple test script that uses the DBRC::
|
4
|
+
# Simple test script that uses the DBRC::YML subclass.
|
5
5
|
#######################################################################
|
6
6
|
if File.basename(Dir.pwd) == "yml"
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
Dir.chdir "../.."
|
8
|
+
$LOAD_PATH.unshift Dir.pwd + "/lib"
|
9
|
+
Dir.chdir "examples/yml"
|
10
10
|
end
|
11
11
|
|
12
12
|
require "dbi/dbrc"
|
data/lib/dbi-dbrc.rb
ADDED
data/lib/dbi/dbrc.rb
CHANGED
@@ -1,34 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
if File::ALT_SEPARATOR
|
2
4
|
require 'win32/dir'
|
3
5
|
require 'win32/file/attributes'
|
4
6
|
require 'win32/process'
|
7
|
+
else
|
8
|
+
require 'etc'
|
9
|
+
require 'gpgme'
|
5
10
|
end
|
6
11
|
|
7
|
-
require 'sys/admin'
|
8
|
-
|
9
12
|
# The DBI module serves as a namespace only.
|
10
13
|
module DBI
|
11
|
-
|
12
14
|
# The DBRC class encapsulates a database resource config file.
|
13
15
|
class DBRC
|
14
|
-
|
15
16
|
# This error is raised if anything fails trying to read the config file.
|
16
17
|
class Error < StandardError; end
|
17
18
|
|
18
19
|
# The version of the dbi-dbrc library
|
19
|
-
VERSION = '1.
|
20
|
+
VERSION = '1.6.0'
|
20
21
|
|
21
|
-
|
22
|
+
WINDOWS = File::ALT_SEPARATOR # :no-doc:
|
22
23
|
|
23
24
|
# The database or host to be connected to.
|
24
25
|
attr_accessor :database
|
25
26
|
|
27
|
+
alias db database
|
28
|
+
alias db= database=
|
29
|
+
alias host database
|
30
|
+
alias host= database=
|
31
|
+
|
26
32
|
# The user name used for the database or host connection.
|
27
33
|
attr_accessor :user
|
28
34
|
|
29
35
|
# The password associated with the database or host.
|
30
36
|
attr_accessor :password
|
31
37
|
|
38
|
+
alias passwd password
|
39
|
+
alias passwd= password=
|
40
|
+
|
32
41
|
# The driver associated with the database. This is used to internally to
|
33
42
|
# construct the DSN.
|
34
43
|
attr_accessor :driver
|
@@ -39,9 +48,15 @@ module DBI
|
|
39
48
|
# The maximum number of reconnects a program should make before giving up.
|
40
49
|
attr_accessor :maximum_reconnects
|
41
50
|
|
51
|
+
alias max_reconn maximum_reconnects
|
52
|
+
alias max_reconn= maximum_reconnects=
|
53
|
+
|
42
54
|
# The timeout, in seconds, for each connection attempt.
|
43
55
|
attr_accessor :timeout
|
44
56
|
|
57
|
+
alias time_out timeout
|
58
|
+
alias time_out= timeout=
|
59
|
+
|
45
60
|
# The interval, in seconds, between each connection attempt.
|
46
61
|
attr_accessor :interval
|
47
62
|
|
@@ -62,7 +77,7 @@ module DBI
|
|
62
77
|
# file.
|
63
78
|
#
|
64
79
|
# If an entry cannot be found for the database, or database plus user
|
65
|
-
# combination, then a Error is raised.
|
80
|
+
# combination, then a Error is raised. If the .dbrc file cannot be
|
66
81
|
# found, or is setup improperly with regards to permissions or properties
|
67
82
|
# then a DBI::DBRC::Error is raised.
|
68
83
|
#
|
@@ -72,6 +87,9 @@ module DBI
|
|
72
87
|
# storage mechanism. In that case simply treat the 'database' as the
|
73
88
|
# host name, and ignore the DBI::DBRC#dsn and DBI::DBRC#driver methods.
|
74
89
|
#
|
90
|
+
# On unixy systems you can GPG encrypt the file, and this library will
|
91
|
+
# decrypt it for you based on the +gpg_options+ that you pass.
|
92
|
+
#
|
75
93
|
# Examples:
|
76
94
|
#
|
77
95
|
# # Find the first match for 'some_database'
|
@@ -83,23 +101,15 @@ module DBI
|
|
83
101
|
# # Find the first match for 'foo_user@some_database' under /usr/local
|
84
102
|
# DBI::DBRC.new('some_database', 'foo_usr', '/usr/local')
|
85
103
|
#
|
86
|
-
|
104
|
+
# # Pass along a GPG password to decrypt the file.
|
105
|
+
# DBI::DBRC.new('some_database', 'foo_usr', '/usr/local', :gpg_options => {:password => 'xxx'})
|
106
|
+
#
|
107
|
+
def initialize(database, user = nil, dbrc_dir = Dir.home, gpg_options = nil)
|
87
108
|
if dbrc_dir.nil?
|
88
|
-
uid = Process.uid
|
89
|
-
home = ENV['HOME'] || ENV['USERPROFILE']
|
90
|
-
|
91
|
-
if home.nil?
|
92
|
-
if @@windows
|
93
|
-
home ||= Sys::Admin.get_user(uid, :localaccount => true).dir
|
94
|
-
else
|
95
|
-
home ||= Sys::Admin.get_user(uid).dir
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
109
|
# Default to the app data directory on Windows, or root on Unix, if
|
100
110
|
# no home dir can be found.
|
101
111
|
if home.nil?
|
102
|
-
if
|
112
|
+
if WINDOWS
|
103
113
|
home = Dir::APPDATA
|
104
114
|
else
|
105
115
|
home = '/'
|
@@ -107,6 +117,7 @@ module DBI
|
|
107
117
|
end
|
108
118
|
|
109
119
|
@dbrc_file = File.join(home, '.dbrc')
|
120
|
+
dbrc_dir = home
|
110
121
|
else
|
111
122
|
raise Error, 'bad directory' unless File.directory?(dbrc_dir)
|
112
123
|
@dbrc_file = File.join(dbrc_dir, '.dbrc')
|
@@ -128,19 +139,26 @@ module DBI
|
|
128
139
|
# Decrypt and re-encrypt the file if we're on MS Windows and the
|
129
140
|
# file is encrypted.
|
130
141
|
begin
|
131
|
-
if
|
142
|
+
if WINDOWS && File.encrypted?(@dbrc_file)
|
132
143
|
file_was_encrypted = true
|
133
144
|
File.decrypt(@dbrc_file)
|
134
145
|
end
|
135
146
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
147
|
+
if gpg_options
|
148
|
+
require 'gpgme'
|
149
|
+
require 'stringio'
|
150
|
+
crypto = GPGME::Crypto.new(gpg_options)
|
151
|
+
stringio = crypto.decrypt(File.open(@dbrc_file))
|
152
|
+
parse_dbrc_config_file(StringIO.new(stringio.read))
|
153
|
+
else
|
154
|
+
parse_dbrc_config_file
|
143
155
|
end
|
156
|
+
|
157
|
+
validate_data
|
158
|
+
convert_numeric_strings
|
159
|
+
create_dsn_string
|
160
|
+
ensure
|
161
|
+
File.encrypt(@dbrc_file) if WINDOWS && file_was_encrypted
|
144
162
|
end
|
145
163
|
end
|
146
164
|
|
@@ -148,28 +166,23 @@ module DBI
|
|
148
166
|
# Ruby Object#inspect, except that the password field is filtered.
|
149
167
|
#
|
150
168
|
def inspect
|
151
|
-
str = instance_variables.map
|
169
|
+
str = instance_variables.map do |iv|
|
152
170
|
if iv == '@password'
|
153
171
|
"#{iv}=[FILTERED]"
|
154
172
|
else
|
155
173
|
"#{iv}=#{instance_variable_get(iv).inspect}"
|
156
174
|
end
|
157
|
-
|
175
|
+
end.join(', ')
|
158
176
|
|
159
|
-
"#<#{self.class}:0x#{(
|
177
|
+
"#<#{self.class}:0x#{(object_id * 2).to_s(16)} " + str + '>'
|
160
178
|
end
|
161
179
|
|
162
180
|
private
|
163
181
|
|
164
182
|
# Ensure that the user/password has been set
|
165
183
|
def validate_data
|
166
|
-
unless @user
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
unless @password
|
171
|
-
raise Error, "password not defined for #{@user}@#{@database}"
|
172
|
-
end
|
184
|
+
raise Error, "no user found associated with #{@database}" unless @user
|
185
|
+
raise Error, "password not defined for #{@user}@#{@database}" unless @password
|
173
186
|
end
|
174
187
|
|
175
188
|
# Converts strings that should be numbers into actual numbers
|
@@ -185,39 +198,33 @@ module DBI
|
|
185
198
|
end
|
186
199
|
|
187
200
|
# Check ownership and permissions
|
188
|
-
def check_file(file
|
189
|
-
File.open(file)
|
201
|
+
def check_file(file = @dbrc_file)
|
202
|
+
File.open(file) do |f|
|
190
203
|
# Permissions must be set to 600 or better on Unix systems.
|
191
204
|
# Must be hidden on Win32 systems.
|
192
|
-
if
|
193
|
-
unless File.hidden?(file)
|
194
|
-
raise Error, "The .dbrc file must be hidden"
|
195
|
-
end
|
205
|
+
if WINDOWS
|
206
|
+
raise Error, 'The .dbrc file must be hidden' unless File.hidden?(file)
|
196
207
|
else
|
197
|
-
unless (f.stat.mode &
|
198
|
-
raise Error, "Bad .dbrc file permissions"
|
199
|
-
end
|
208
|
+
raise Error, 'Bad .dbrc file permissions' unless (f.stat.mode & 0o77) == 0
|
200
209
|
end
|
201
210
|
|
202
211
|
# Only the owner may use it
|
203
|
-
unless f.stat.owned?
|
204
|
-
|
205
|
-
end
|
206
|
-
}
|
212
|
+
raise Error, 'Not owner of .dbrc file' unless f.stat.owned?
|
213
|
+
end
|
207
214
|
end
|
208
215
|
|
209
216
|
# Parse the text out of the .dbrc file. This is the only method you
|
210
217
|
# need to redefine if writing your own config handler.
|
211
|
-
def parse_dbrc_config_file(file
|
212
|
-
|
213
|
-
|
218
|
+
def parse_dbrc_config_file(file = @dbrc_file)
|
219
|
+
begin
|
220
|
+
fh = file.is_a?(StringIO) ? file : File.open(file)
|
221
|
+
|
222
|
+
fh.each_line do |line|
|
223
|
+
next if line =~ /^#/ # Ignore comments
|
214
224
|
db, user, pwd, driver, timeout, max, interval = line.split
|
215
225
|
|
216
226
|
next unless @database == db
|
217
|
-
|
218
|
-
if @user
|
219
|
-
next unless @user == user
|
220
|
-
end
|
227
|
+
next if @user && @user != user
|
221
228
|
|
222
229
|
@user = user
|
223
230
|
@password = pwd
|
@@ -225,83 +232,75 @@ module DBI
|
|
225
232
|
@timeout = timeout
|
226
233
|
@maximum_reconnects = max
|
227
234
|
@interval = interval
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
err = "no record found for #{@user}@#{@database}"
|
234
|
-
else
|
235
|
-
err = "no record found for #{@database}"
|
236
|
-
end
|
235
|
+
break
|
236
|
+
end
|
237
|
+
ensure
|
238
|
+
fh.close if fh && fh.respond_to?(:close)
|
239
|
+
end
|
237
240
|
|
238
|
-
|
241
|
+
if @user
|
242
|
+
raise Error, "no record found for #{@user}@#{@database}" unless @user
|
243
|
+
else
|
244
|
+
raise Error, "no record found for #{@database}" unless @database
|
245
|
+
end
|
239
246
|
end
|
240
|
-
|
241
|
-
alias_method(:db, :database)
|
242
|
-
alias_method(:db=, :database=)
|
243
|
-
alias_method(:passwd, :password)
|
244
|
-
alias_method(:passwd=, :password=)
|
245
|
-
alias_method(:max_reconn, :maximum_reconnects)
|
246
|
-
alias_method(:max_reconn=, :maximum_reconnects=)
|
247
|
-
alias_method(:time_out, :timeout)
|
248
|
-
alias_method(:time_out=, :timeout=)
|
249
|
-
alias_method(:host, :database)
|
250
247
|
end
|
251
248
|
|
252
249
|
# A subclass of DBRC designed to handle .dbrc files in XML format. The
|
253
250
|
# public methods of this class are identical to DBRC.
|
254
|
-
class XML < DBRC
|
255
|
-
require
|
256
|
-
include REXML
|
251
|
+
class DBRC::XML < DBRC
|
252
|
+
require 'rexml/document' # Good enough for small files
|
257
253
|
|
258
254
|
private
|
259
255
|
|
260
|
-
def parse_dbrc_config_file(file
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
256
|
+
def parse_dbrc_config_file(file = @dbrc_file)
|
257
|
+
file = file.is_a?(StringIO) ? file : File.new(file)
|
258
|
+
doc = REXML::Document.new(file)
|
259
|
+
|
260
|
+
fields = %w[user password driver interval timeout maximum_reconnects]
|
261
|
+
|
262
|
+
doc.elements.each('/dbrc/database') do |element|
|
263
|
+
next unless element.attributes['name'] == database
|
264
|
+
next if @user && @user != element.elements['user'].text
|
265
|
+
|
266
|
+
fields.each do |field|
|
269
267
|
val = element.elements[field]
|
270
|
-
unless val.nil?
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
raise Error, "No record found for #{@user}@#{@database}"
|
268
|
+
send("#{field}=", val.text) unless val.nil?
|
269
|
+
end
|
270
|
+
|
271
|
+
break
|
272
|
+
end
|
273
|
+
|
274
|
+
raise Error, "No record found for #{@user}@#{@database}" unless @user && @database
|
278
275
|
end
|
279
276
|
end
|
280
277
|
|
281
278
|
# A subclass of DBRC designed to handle .dbrc files in YAML format. The
|
282
279
|
# public methods of this class are identical to DBRC.
|
283
|
-
class YML < DBRC
|
284
|
-
require
|
280
|
+
class DBRC::YML < DBRC
|
281
|
+
require 'yaml'
|
285
282
|
|
286
283
|
private
|
287
284
|
|
288
|
-
def parse_dbrc_config_file(file
|
289
|
-
|
290
|
-
config.
|
291
|
-
|
285
|
+
def parse_dbrc_config_file(file = @dbrc_file)
|
286
|
+
fh = file.is_a?(StringIO) ? file : File.open(file)
|
287
|
+
config = YAML.safe_load(fh)
|
288
|
+
|
289
|
+
config.each do |hash|
|
290
|
+
hash.each do |db, info|
|
292
291
|
next unless db == @database
|
293
|
-
next
|
294
|
-
@user
|
295
|
-
@password
|
296
|
-
@driver
|
297
|
-
@interval
|
298
|
-
@timeout
|
299
|
-
@maximum_reconnects = info[
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
raise Error, "No entry found for #{@user}@#{@database}"
|
292
|
+
next if @user && @user != info['user']
|
293
|
+
@user = info['user']
|
294
|
+
@password = info['password']
|
295
|
+
@driver = info['driver']
|
296
|
+
@interval = info['interval']
|
297
|
+
@timeout = info['timeout']
|
298
|
+
@maximum_reconnects = info['maximum_reconnects']
|
299
|
+
break
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
raise Error, "No entry found for #{@user}@#{@database}" unless @user && @database
|
305
304
|
end
|
306
305
|
end
|
307
306
|
end
|