Aft er
getopt
ret urns - 1 t o indicat e t hat no m ore opt ions were found in t he argum ent array,
getOptind
ret urns t he index of t he first argum ent following t he last opt ion. The following code fragm ent shows one way t o access t he rem aining argum ent s:
for int i = g.getOptind ; i args.length; i++ System.out.println args[i];
The
Getopt
class offers ot her opt ion-processing behavior in addit ion t o what I ve described here. Read t he docum ent at ion included wit h t he class for m ore inform at ion.
One deficiency of Cm dline.j ava t hat you m ay want t o address is t hat it doesnt disable charact er echoing while it s reading t he password.
2.11.5 Getting Parameters from Option Files
I f your API allows it , you can specify connect ion param et ers in a MySQL opt ion file and t he API will read t he param et ers from t he file for you. For API s t hat do not support opt ion files
direct ly, you m ay be able t o arrange t o read ot her t ypes of files in which param et ers are st ored, or t o writ e your own funct ions t hat read opt ion files.
The form at of opt ion files was described in Chapt er 1
. I ll assum e t hat youve read t he discussion t here and concent rat e here on how t o use opt ion files from wit hin program s. Under
Unix, user- specific opt ions are specified by convent ion in ~ .m y.cnf t hat is, in t he .m y.cnf file in your hom e direct ory . However, t he MySQL opt ion file m echanism can look in several
different files. The st andard search order is et c m y.cnf, t he m y.cnf file in t he servers default dat a direct ory, and t he ~ .m y.cnf file for t he current user. Under Windows, t he search order is
t he m y.ini file in t he Window s syst em direct ory, C: \ m y.cnf, and t he m y.cnf file in t he servers default dat a direct ory. I f m ult iple opt ion files exist and a param et er is specified in several of
t hem , t he last value found t akes precedence. However, it s not an error for any given opt ion file not t o exist .
MySQL opt ion files will not be used by your own program s unless you t ell t hem t o do so. Perl and Pyt hon provide direct API support for reading opt ion files; sim ply indicat e t hat you want t o
use t hem at t he t im e t hat you connect t o t he server. I t s possible t o specify t hat only a part icular file should be read, or t hat t he st andard search order should be used t o look for
m ult iple opt ion files. PHP and Java do not support opt ion files. As a workaround for PHP, well writ e a sim ple opt ion file parsing funct ion. For Java, well adopt a different approach t hat uses
propert ies files. Alt hough t he convent ional nam e under Unix for t he user-specific opt ion file is .m y.cnf in t he
current users hom e direct ory, t heres no rule your program s m ust use t his part icular file. You can nam e an opt ion file anyt hing you like and put it wherever you want . For exam ple, you
m ight set up a file usr local apache lib cb.cnf for use by web script s t hat access t he
cookbook
dat abase. Under som e circum st ances, you m ay even want t o creat e m ult iple files. Then, from wit hin any given script , you can select t he file t hat s appropriat e for t he t ype of
perm issions t he script needs. For exam ple, you m ight have one opt ion file, cb.cnf, t hat list s
param et ers for a full- access MySQL account , and anot her file, cb- ro.cnf, t hat list s connect ion param et ers for an account t hat needs only read- only access t o MySQL. Anot her possibilit y is t o
list m ult iple groups wit hin t he sam e opt ion file and have your script s select opt ions from t he appropriat e group.
C API Support for Option Files
The Perl and Pyt hon API s are built using t he C API , and opt ion file support was not added t o t he C client library unt il MySQL 3.22.10. This m eans t hat even for Perl and
Pyt hon, you m ust have MySQL 3.22.10 or lat er t o use opt ion files from wit hin your own program s.
Hist orically, t he dat abase nam e has not been a param et er you get from an opt ion file. Program s t ypically provide t his value t hem selves or expect t he user t o specify
it . As of MySQL 3.23.6, support was added t o t he C client library t o look for opt ion file lines of t he form
database= db_name
, but t he exam ples in t his sect ion do not use t his fact .
2 .1 1 .5 .1 Pe r l
Perl DBI script s can use opt ion files if you have DBD: : m ysql 1.21.06 or lat er. To t ake advant age of t his, place t he appropriat e opt ion specifiers in t he t hird com ponent of t he dat a
source nam e st ring:
•
To specify an opt ion group, use
mysql_read_default_group= groupname
. This t ells MySQL t o search t he st andard opt ion files for opt ions in t he nam ed group and in
t he
[client]
group. The
groupname
value should be writ t en wit hout t he square bracket s t hat are part of t he line t hat begins t he group. For exam ple, if a group in an
opt ion file begins w it h a
[my_prog]
line, specify
my_prog
as t he
groupname
value. To search t he st andard files but look only in t he
[client]
group,
groupname
should be
client
.
•
To nam e a specific opt ion file, use
mysql_read_default_file= filename
in t he DSN. When you do t his, MySQL looks only in t hat file, and only for opt ions in t he
[client]
group.
•
I f you specify bot h an opt ion file and an opt ion group, MySQL reads only t he nam ed file, but looks for opt ions bot h in t he nam ed group and in t he
[client]
group. The following exam ple t ells MySQL t o use t he st andard opt ion file search order t o look for
opt ions in bot h t he
[cookbook]
and
[client]
groups: basic DSN
my dsn = DBI:mysql:database=cookbook; look in standard option files; use [cookbook] and [client] groups
dsn .= ;mysql_read_default_group=cookbook; my dbh = DBI-connect dsn, undef, undef,
{ PrintError = 0, RaiseError = 1 };
The next exam ple explicit ly nam es t he opt ion file locat ed in
ENV{HOME}
, t he hom e direct ory of t he user running t he script . Thus, MySQL will look only in t hat file and will use opt ions from
t he
[client]
group: basic DSN
my dsn = DBI:mysql:database=cookbook; look in user-specific option file owned by the current user
dsn .= ;mysql_read_default_file=ENV{HOME}.my.cnf; my dbh = DBI-connect dsn, undef, undef,
{ PrintError = 0, RaiseError = 1 };
I f you pass an em pt y value
undef
or t he em pt y st ring for t he usernam e or password argum ent s of t he
connect
call,
connect
uses what ever values are found in t he opt ion file or files. A nonem pt y usernam e or password in t he
connect
call overrides any opt ion file value. Sim ilarly, a host nam ed in t he DSN overrides any opt ion file value. You can
use t his behavior t o allow DBI script s t o obt ain connect ion param et ers bot h from opt ion files as well as from t he com m and line as follows:
1. Cr eat e host_name
, user_name
, and password
v ar iables and init ialize t hem t o undef
. Then par se t he com m and- line argum ent s t o set t he variables t o non-
undef values if t he corresponding opt ions are present on t he com m and line.
See t he Perl script earlier in t his sect ion t o see how t his is done. 2. Aft er par sing t he com m and ar gum ent s, const r uct t he DSN st r ing and call
connect . Use
mysql_read_default_group and
mysql_read_default_file in t he DSN t o specify how you w ant opt ion files t o be
used, and, if host_name
is not undef
, add host=host_name
t o t he DSN. I n addit ion, pass user_name
and password
as t he user nam e and passw or d ar gum ent s t o connect
. These w ill be undef
by default ; if t hey w er e set from t he com m and- line argum ent s, t hey w ill have non-
undef values t hat override any opt ion file values.
I f a script follows t his procedure, param et ers given by t he user on t he com m and line are passed t o
connect
and t ake precedence over t he cont ent s of opt ion files.
2 .1 1 .5 .2 PH P
PHP has no nat ive support for using MySQL opt ion files, at least at t he m om ent . To work around t hat lim it at ion, use a funct ion t hat reads an opt ion file, such as t he
read_mysql_option_file
funct ion shown below. I t t akes as argum ent s t he nam e of an opt ion file and an opt ion group nam e or an array cont aining group nam es. Group nam es
should be nam ed wit hout square bracket s. Then it reads any opt ions present in t he file for t he nam ed group or groups. I f no opt ion group argum ent is given, t he funct ion looks by
default in t he
[client]
group. The ret urn value is an array of opt ion nam e value pairs, or
FALSE
if an error occurs. I t is not an error for t he file not t o exist . function read_mysql_option_file filename, group_list = client
{ if is_string group_list convert string to array
group_list = array group_list; if is_array group_list hmm ... garbage argument?
return FALSE; opt = array ; option namevalue array
if fp = fopen filename, r if file does not exist, return opt; return an empty list
in_named_group = 0; set non-zero while processing a named group while s = fgets fp, 1024
{ s = trim s;
if ereg [;], s skip comments continue;
if ereg \[[]]+], s, arg option group line? {
check whether were in one of the desired groups in_named_group = 0;
reset group_list; while list key, group_name = each group_list
{ if arg[1] == group_name
{ in_named_group = 1; we are
break; }
} continue;
} if in_named_group were not in a desired
continue; group, skip the line if ereg [ \t=]+[ \t]=[ \t]., s, arg
opt[arg[1]] = arg[2]; name=value else if ereg [ \t]+, s, arg
opt[arg[1]] = ; name only else line is malformed
} return opt;
}
Here are a couple of exam ples showing how t o use
read_mysql_option_file
. The first reads a users opt ion file t o get t he
[client]
group param et ers, t hen uses t hem t o connect t o t he server. The second reads t he syst em -wide opt ion file and print s t he server st art up
param et ers t hat are found t here t hat is, t he param et ers in t he
[mysqld]
and
[server]
groups : opt = read_mysql_option_file upaul.my.cnf;
link = mysql_connect opt[host], opt[user], opt[password]; opt = read_mysql_option_file etcmy.cnf, array mysqld, server;
while list name, value = each opt print name = value\n;
I f youre using t he
MySQL_Access
int erface t hat was developed in Recipe 2.10
, you m ight t hink about how t o ext end t he class by im plem ent ing a derived class t hat get s t he usernam e,
password, and host nam e from an opt ion file. You could also give t his derived class t he abilit y t o search m ult iple files, which is an aspect of t he usual opt ion file behavior t hat
read_mysql_option_file
does not provide.
2 .1 1 .5 .3 Pyt h on
The MySQLdb m odule for DB- API provides direct support for using MySQL opt ion files. Specify an opt ion file or opt ion group using
read_default_file
or
read_default_group
argum ent s t o t he
connect
m et hod. These t wo argum ent s act t he sam e way as t he
mysql_read_default_file
and
mysql_read_default_group
opt ions for t he Perl DBI
connect
m et hod see t he Perl discussion earlier in t his sect ion . To use t he st andard opt ion file search order t o look for opt ions in bot h t he
[cookbook]
and
[client]
groups, do som et hing like t his:
try: conn = MySQLdb.connect db = cookbook, read_default_group =
cookbook print Connected
except: print Cannot connect to server
sys.exit 1
The following exam ple shows how t o use t he .m y.cnf file in t he current users hom e direct ory t o obt ain param et ers from t he
[client]
group:
[ 8] [ 8]
You m ust im port t he
os
m odule t o access
os.environ
. try:
option_file = os.environ[HOME] + + .my.cnf conn = MySQLdb.connect db = cookbook, read_default_file =
option_file print Connected
except: print Cannot connect to server
sys.exit 1
2 .1 1 .5 .4 Ja va
The MySQL Connect or J JDBC driver doesnt support opt ion files. However, t he Java class library provides support for reading propert ies files t hat cont ain lines in
name=value
form at . This is som ewhat sim ilar t o MySQL opt ion file form at , alt hough t here are som e differences for
exam ple, propert ies files do not allow
[ groupname
] lines . Here is a sim ple propert ies file: this file lists parameters for connecting to the MySQL server
user=cbuser password=cbpass
host=localhost
The following program , ReadPropsFile.j ava, shows one way t o read a propert ies file nam ed Cookbook.propert ies t o obt ain connect ion param et ers. The file m ust be in a direct ory nam ed in
your
CLASSPATH
variable, or else you m ust specify it using a full pat hnam e t he exam ple shown here assum es t he file is in a
CLASSPATH
direct ory : import java.sql.;
import java.util.; need this for properties file support
public class ReadPropsFile {
public static void main String[ ] args {
Connection conn = null; String url = null;
String propsFile = Cookbook.properties; Properties props = new Properties ;
try {
props.load ReadPropsFile.class.getResourceAsStream propsFile;
} catch Exception e
{ System.err.println Cannot read properties file;
System.exit 1; }
try {
construct connection URL, encoding username and password as parameters at the end
url = jdbc:mysql: + props.getProperty host
+ cookbook + ?user= + props.getProperty user
+ password= + props.getProperty password; Class.forName com.mysql.jdbc.Driver.newInstance ;
conn = DriverManager.getConnection url; System.out.println Connected;
} catch Exception e
{ System.err.println Cannot connect to server;
} finally
{ try
{ if conn = null
{ conn.close ;
System.out.println Disconnected; }
} catch SQLException e { ignore close errors }
} }
}
I f you w ant
getProperty
t o ret urn a part icular default value when t he nam ed propert y is not found, pass t hat value as a second argum ent . For exam ple, t o use
localhost
as t he default
host
value, call
getProperty
like t his: String hostName = props.getProperty host, localhost;
The Cookbook.class library file developed earlier in t he chapt er Recipe 2.4
includes a
propsConnect
rout ine t hat is based on t he concept s discussed here. To use it , set up t he cont ent s of t he propert ies file, Cookbook.propert ies, and copy t he file t o t he sam e locat ion
where you inst alled Cookbook.class. Then you can est ablish a connect ion wit hin a program by im port ing t he
Cookbook
class and calling
Cookbook.propsConnect
rat her t han by calling
Cookbook.connect
.
2.12 Conclusion and Words of Advice