dbi-dbrc 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +7 -0
- data/examples/plain/test.rb +21 -21
- data/examples/xml/test_xml.rb +28 -28
- data/examples/yml/test_yml.rb +28 -28
- data/lib/dbi/dbrc.rb +231 -229
- data/test/tc_dbrc.rb +178 -178
- data/test/tc_dbrc_xml.rb +160 -160
- data/test/tc_dbrc_yml.rb +165 -165
- data/test/ts_all.rb +6 -6
- metadata +52 -36
data/CHANGES
CHANGED
@@ -1,3 +1,10 @@
|
|
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
|
+
|
1
8
|
== 1.1.1 - 2-Aug-2007
|
2
9
|
* DBRCError is now DBRC::Error.
|
3
10
|
* Added a Rakefile with tasks for installation and testing.
|
data/examples/plain/test.rb
CHANGED
@@ -1,21 +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
|
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
|
data/examples/xml/test_xml.rb
CHANGED
@@ -1,28 +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
|
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
|
data/examples/yml/test_yml.rb
CHANGED
@@ -1,28 +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
|
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
|
data/lib/dbi/dbrc.rb
CHANGED
@@ -1,229 +1,231 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# entry
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# be found
|
36
|
-
#
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
file = File.join(
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@dbrc_file =
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@
|
65
|
-
@
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
@
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
@
|
150
|
-
@
|
151
|
-
@
|
152
|
-
@
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
err = "no record found for #{@database}"
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
alias_method(:
|
169
|
-
alias_method(:
|
170
|
-
alias_method(:
|
171
|
-
alias_method(:
|
172
|
-
alias_method(:
|
173
|
-
alias_method(:
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
doc.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
@
|
219
|
-
@
|
220
|
-
@
|
221
|
-
@
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
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
|