Class: JSS::DBConnection
- Includes:
- Singleton
- Defined in:
- lib/jss/db_connection.rb,
lib/jss.rb
Overview
A mysql connection to the JSS database.
This is a singleton class, only one can exist at a time, and it is created, but not connected, automatically when the module loads.
Use it via the JSS::DB_CNX constant (for connection metadata) and the JSS::DB_CNX.db attribute (which contains the actual mysql query interface) for making queries
Direct MySQL access is minimal and discouraged, since it bypasses the API, and can be very dangerous. However, it's necessary to overcome some limitations of the API or to access custom tables.
While a database connction isn't required for most things, warnings will be sent to stderr when functionality is limited due to a lack of a database connection i.e. when JSS::DB_CNX.connected? == false
To make a connection with credentials, just call the #connect method thus:
JSS::DB_CNX.connect :server => 'server.company.com', :user => "user", :pw => "pw"
Other options include:
:db_name => which database to connect to, defaults to 'jamfsoftware'
:port => tcp port for connection to server, defaults to the standard mysql port.
:connect_timeout => seconds to wait before giving up on connection, defaults to 120
:read_timeout => seconds to wait before giving up on recieving data, defaults to 120
:write_timeout => seconds to wait before giving up on sending data, defaults to 120
:timeout => sets all three timeouts to the same value, defaults to 120
Calling JSS::DB_CNX.connect again will re-use any values not provided. but will create a new connection.
Constant Summary collapse
- DEFAULT_DB_NAME =
The name of the JSS database on the mysql server
'jamfsoftware'.freeze
- DFT_TIMEOUT =
give the connection a 60 second timeout, for really slow net connections (likeā¦ from airplanes)
60
- DFT_SOCKET =
'/var/mysql/mysql.sock'.freeze
- DFT_PORT =
the default MySQL port
3306
- DFT_CHARSET =
The default encoding in the tables - JAMF wisely uses UTF-8
'utf8'.freeze
- SQL_DATE_FORMAT =
the strftime format for reading/writing dates in the db
'%Y-%m-%d %H:%M:%S'.freeze
Instance Attribute Summary collapse
-
#connect_timeout ⇒ Object
readonly
Returns the value of attribute connect_timeout.
-
#connected ⇒ Object
(also: #connected?)
readonly
Returns the value of attribute connected.
-
#db_name ⇒ Object
readonly
Returns the value of attribute db_name.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#read_timeout ⇒ Object
readonly
Returns the value of attribute read_timeout.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#socket ⇒ Object
readonly
Returns the value of attribute socket.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
-
#write_timeout ⇒ Object
readonly
Returns the value of attribute write_timeout.
Instance Method Summary collapse
-
#connect(args = {}) ⇒ true
Connect to the JSS MySQL database.
-
#db ⇒ Mysql
The mysql database connection itself.
-
#disconnect ⇒ Object
close the connection to the database it'll have to be re-connected before using again.
-
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect.
-
#initialize ⇒ DBConnection
constructor
A new instance of DBConnection.
-
#valid_server?(server, port = DFT_PORT) ⇒ Boolean
Test that a given hostname is a MySQL server.
Constructor Details
#initialize ⇒ DBConnection
Returns a new instance of DBConnection.
106 107 108 109 110 |
# File 'lib/jss/db_connection.rb', line 106 def initialize require 'mysql' @mysql = Mysql.init @connected = false end |
Instance Attribute Details
#connect_timeout ⇒ Object (readonly)
Returns the value of attribute connect_timeout.
101 102 103 |
# File 'lib/jss/db_connection.rb', line 101 def connect_timeout @connect_timeout end |
#connected ⇒ Object (readonly) Also known as: connected?
Returns the value of attribute connected.
104 105 106 |
# File 'lib/jss/db_connection.rb', line 104 def connected @connected end |
#db_name ⇒ Object (readonly)
Returns the value of attribute db_name.
100 101 102 |
# File 'lib/jss/db_connection.rb', line 100 def db_name @db_name end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
97 98 99 |
# File 'lib/jss/db_connection.rb', line 97 def port @port end |
#read_timeout ⇒ Object (readonly)
Returns the value of attribute read_timeout.
102 103 104 |
# File 'lib/jss/db_connection.rb', line 102 def read_timeout @read_timeout end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
96 97 98 |
# File 'lib/jss/db_connection.rb', line 96 def server @server end |
#socket ⇒ Object (readonly)
Returns the value of attribute socket.
98 99 100 |
# File 'lib/jss/db_connection.rb', line 98 def socket @socket end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
99 100 101 |
# File 'lib/jss/db_connection.rb', line 99 def user @user end |
#write_timeout ⇒ Object (readonly)
Returns the value of attribute write_timeout.
103 104 105 |
# File 'lib/jss/db_connection.rb', line 103 def write_timeout @write_timeout end |
Instance Method Details
#connect(args = {}) ⇒ true
Connect to the JSS MySQL database.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/jss/db_connection.rb', line 143 def connect(args = {}) begin disconnect if @connected rescue Mysql::ClientError::ServerGoneError @connected = false end # server might come frome several places # if not given in the args, use #hostname to figure out # which @server = args[:server] ? args[:server] : hostname # settings from config if they aren't in the args args[:port] ||= JSS::CONFIG.db_server_port ? JSS::CONFIG.db_server_port : Mysql::MYSQL_TCP_PORT args[:socket] ||= JSS::CONFIG.db_server_socket ? JSS::CONFIG.db_server_socket : DFT_SOCKET args[:db_name] ||= JSS::CONFIG.db_name ? JSS::CONFIG.db_name : DEFAULT_DB_NAME args[:user] ||= JSS::CONFIG.db_username args[:connect_timeout] ||= JSS::CONFIG.db_connect_timeout args[:read_timeout] ||= JSS::CONFIG.db_read_timeout args[:write_timeout] ||= JSS::CONFIG.db_write_timeout args[:charset] ||= DFT_CHARSET ### if one timeout was given, use it for all three args[:connect_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT args[:read_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT args[:write_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT @port = args[:port] @socket = args[:socket] @mysql_name = args[:db_name] @user = args[:user] @connect_timeout = args[:connect_timeout] @read_timeout = args[:read_timeout] @write_timeout = args[:write_timeout] # make sure we have a user, pw, server raise JSS::MissingDataError, 'No MySQL user specified, or defined in configuration.' unless args[:user] raise JSS::MissingDataError, "Missing :pw (or :prompt/:stdin) for user '#{@user}'" unless args[:pw] raise JSS::MissingDataError, 'No MySQL Server hostname specified, or listed in configuration.' unless @server @pw = if args[:pw] == :prompt JSS.prompt_for_password "Enter the password for the MySQL user #{@user}@#{@server}:" elsif args[:pw].is_a?(Symbol) && args[:pw].to_s.start_with?('stdin') args[:pw].to_s =~ /^stdin(\d+)$/ line = Regexp.last_match(1) line ||= 2 JSS.stdin line else args[:pw] end @mysql = Mysql.init @mysql. Mysql::OPT_CONNECT_TIMEOUT, @connect_timeout @mysql. Mysql::OPT_READ_TIMEOUT, @read_timeout @mysql. Mysql::OPT_WRITE_TIMEOUT, @write_timeout @mysql.charset = args[:charset] @mysql.connect @server, @user, @pw, @mysql_name, @port, @socket @connected = true @server rescue Mysql::ServerError::NotSupportedAuthMode => e raise Mysql::ServerError::AccessDeniedError, "Probable unknown MySQL user '#{@user}'. Original error was 'Mysql::ServerError::NotSupportedAuthMode: #{e}' which is sometimes raised when the user does not exist on the server." end |
#db ⇒ Mysql
Returns The mysql database connection itself.
212 213 214 215 |
# File 'lib/jss/db_connection.rb', line 212 def db raise JSS::InvalidConnectionError, 'No database connection. Please use JSS::DB_CNX.connect' unless JSS::DB_CNX.connected? @mysql end |
#disconnect ⇒ Object
close the connection to the database it'll have to be re-connected before using again
221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/jss/db_connection.rb', line 221 def disconnect @mysql.close! if @mysql.protocol @server = nil @port = nil @socket = nil @user = nil @connection_timeout = DFT_TIMEOUT @read_timeout = DFT_TIMEOUT @write_timeout = DFT_TIMEOUT @connected = false nil end |
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect
271 272 273 274 275 276 277 278 279 |
# File 'lib/jss/db_connection.rb', line 271 def hostname # return it if already set return @server if @server # otherwise, from the config srvr = JSS::CONFIG.db_server_name # otherwise, assume its on the JSS server to which this client talks srvr ||= JSS::Client.jss_server srvr end |
#valid_server?(server, port = DFT_PORT) ⇒ Boolean
Test that a given hostname is a MySQL server
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/jss/db_connection.rb', line 240 def valid_server?(server, port = DFT_PORT) mysql = Mysql.init mysql. Mysql::OPT_CONNECT_TIMEOUT, 60 mysql.charset = DFT_CHARSET begin # this connection should get an access denied error if there is # a mysql server there. I'm assuming no one will use this username # and pw for anything real # Also with newer versions of mysql, a Mysql instance that has # never authenticated will raise Mysql::ServerError::NotSupportedAuthMode # rather than Mysql::ServerError::AccessDeniedError, until a # successful connection is made. After that, re-connecting will # raise AccessDeniedError when credentials are invalid. mysql.connect server, 'notArealUser', "definatelyNotA#{$PROCESS_ID}password", 'not_a_db', port rescue Mysql::ServerError::AccessDeniedError, Mysql::ServerError::NotSupportedAuthMode return true rescue return false end false end |