1Rose::DB::Tutorial(3) User Contributed Perl DocumentationRose::DB::Tutorial(3)
2
3
4
6 Rose::DB::Tutorial - Best practices for using Rose::DB
7
9 This tutorial describes "best practices" for using Rose::DB in the most
10 robust, maintainable manner. It does not replace the actual
11 documentation, however. The actual Rose::DB documentation is still
12 essential, and contains some good examples of its own.
13
14 In particular, you should read the description section of the Rose::DB
15 documentation if you have not done so already. It describes the
16 features and philosophy of Rose::DB. That information that will not be
17 repeated here.
18
20 The examples in this tutorial will use the fictional "My::" namespace
21 prefix. Your code should use whatever namespace you deem appropriate.
22 Usually, it will be more akin to "MyCorp::MyProject::" (i.e., your
23 corporation, organization, and/or project). I've chosen to use "My::"
24 simply because it's shorter, and will help this tutorial stay within an
25 80-column width.
26
27 For the sake of brevity, the "use strict" directive and associated "my"
28 declarations have been omitted from the example code. Needless to say,
29 you should always "use strict" in your actual code.
30
31 Similarly, the traditional "1;" true value used at the end of each
32 ".pm" file has been omitted from the examples. Don't forget to add
33 this to the end of your actual Perl module files.
34
36 Creating a subclass
37 The first step when using Rose::DB in anything but a throw-away script
38 is to create a trivial subclass. This is important because Rose::DB
39 has a significant amount of class data. Using Rose::DB directly means
40 that you will be reading and writing the same data as any other badly-
41 behaved code that also uses Rose::DB directly.
42
43 In particular, the registry that contains all the information for each
44 data source is class data, and is inherited from (that is, shared with)
45 the base class by default. Creating a subclass allows you to have your
46 own, private data source registry.
47
48 So, here's our initial Rose::DB subclass.
49
50 # File: My/DB.pm
51 package My::DB;
52
53 use Rose::DB;
54 our @ISA = qw(Rose::DB);
55
56 # Use a private registry for this class
57 __PACKAGE__->use_private_registry;
58
59 Designing your namespace
60 As described in the Rose::DB documentation, Rose::DB provides a two-
61 level namespace for data sources, made up of a "domain" and a "type."
62 These are both arbitrary strings, so there's a lot of freedom to break
63 up the namespace in any way you see fit. For example, sub-domains and
64 sub-types can be created within each string using delimiter characters
65 (e.g., "::" as in Perl's package namespace).
66
67 But let's back up. The simplest case is that you have just one data
68 source, and therefore no need for a namespace at all. If this is the
69 case, you can skip to the next section.
70
71 In the common case, it's usually sufficient to use simple words for
72 both type and domain. As the name "domain" implies, this value usually
73 represents the environment or surroundings. For example, a typical
74 server application might use domains named "development", "qa",
75 "staging", and "production".
76
77 The "type" portion of the namespace tends to be used to differentiate
78 the applicability or contents of the data sources. Some example type
79 names are "main" for the primary database, "archive" for a data
80 warehouse database, and "session" for a database used to store
81 transient session data.
82
83 The goal of namespace design is to allow data sources to be referred to
84 symbolically, with names that make sense to you in your environment.
85
86 Registering data sources
87 Now that you've decided on your namespace design (or lack thereof, if
88 you have only one data source), it's time to register some data
89 sources. To register a data source, call the register_db class method.
90
91 This can be done nearly anywhere, but it's most convenient to do it
92 "early" and to link it somehow to your "My::DB" subclass. That is,
93 when someone "use"s "My::DB", they should not have to worry about
94 whether or not all the data sources are registered.
95
96 In a server environment, there's usually some sort of start-up file
97 that gets loaded before any "end-user" code (e.g., "startup.pl" by
98 convention in a mod_perl Apache web server). That may be a good place
99 to include your data source registration calls, but only if you're
100 absolutely sure that "My::DB" will never be used outside the server
101 environment.
102
103 A better, safer alternative is to put the data source registration
104 calls directly in your Rose::DB subclass. This is the recommended
105 approach. Here are some examples.
106
107 Just one data source
108
109 First, consider the case where a namespace is not necessary. You have
110 a single data source and that's all. You don't care what it's named.
111 Luckily, there are default values for both type and domain. Simply
112 register your data source using these values and you're all set.
113
114 package My::DB;
115
116 use Rose::DB;
117 our @ISA = qw(Rose::DB);
118
119 # Use a private registry for this class
120 __PACKAGE__->use_private_registry;
121
122 # Register your lone data source using the default type and domain
123 __PACKAGE__->register_db(
124 domain => My::DB->default_domain,
125 type => My::DB->default_type,
126 driver => 'pg',
127 database => 'my_db',
128 host => 'localhost',
129 username => 'joeuser',
130 password => 'mysecret',
131 );
132
133 The domain and type parameters can actually be omitted entirely and
134 they will still default to the values shown above. In other words, the
135 following call to register_db is exactly equivalent to the one above.
136
137 # Register your lone data source using the default type and domain
138 __PACKAGE__->register_db(
139 driver => 'pg',
140 database => 'my_db',
141 host => 'localhost',
142 username => 'joeuser',
143 password => 'mysecret',
144 );
145
146 To use "My::DB" in this kind of setup, simply omit the domain and type
147 parameters from your calls to "My::DB->new". They will automatically
148 get the default values.
149
150 use My::DB;
151
152 $db = My::DB->new(); # use default type and default domain
153 print $db->username; # "joeuser"
154 $dbh = $db->dbh; # connect and get DBI database handle
155
156 Multiple data sources
157
158 Most commonly, you will have more than one data source. (And if you
159 don't now, you probably will in the future. Better safe than sorry.)
160 After you've designed your namespace, data source registration is
161 straightforward. The only wrinkle is how to deal with the default
162 domain and type.
163
164 I recommend setting the default domain and type to the "safest" values
165 in your environment. For example, a domain of "development" and a type
166 of "main" are reasonable choices. This allows you to use "bare" calls
167 to "My::DB->new()" in your code (as shown in the simple, single data
168 source example above).
169
170 Here's an example that includes two domains "development" and
171 "production", and two types, "main" and "session." The default data
172 source is the domain "development" and the type "main".
173
174 package My::DB;
175
176 use Rose::DB;
177 our @ISA = qw(Rose::DB);
178
179 # Use a private registry for this class
180 __PACKAGE__->use_private_registry;
181
182 # Set the default domain and type
183 __PACKAGE__->default_domain('development');
184 __PACKAGE__->default_type('main');
185
186 # Register the data sources
187
188 # Development:
189
190 __PACKAGE__->register_db(
191 domain => 'development',
192 type => 'main',
193 driver => 'pg',
194 database => 'dev_db',
195 host => 'localhost',
196 username => 'devuser',
197 password => 'mysecret',
198 );
199
200 __PACKAGE__->register_db(
201 domain => 'development',
202 type => 'session',
203 driver => 'mysql',
204 database => 'session_db',
205 host => 'localhost',
206 username => 'devmysql',
207 password => 'mysqlpw',
208 );
209
210 # Production:
211
212 __PACKAGE__->register_db(
213 domain => 'production',
214 type => 'main',
215 driver => 'pg',
216 database => 'big_db',
217 host => 'dbserver.mycorp.com',
218 username => 'dbadmin',
219 password => 'prodsecret',
220 );
221
222 __PACKAGE__->register_db(
223 domain => 'production',
224 type => 'session',
225 driver => 'mysql',
226 database => 'session_db',
227 host => 'sessions.mycorp.com',
228 username => 'session_user',
229 password => 'prodsesspw',
230 );
231
232 Ideally, and as shown in the example above, all data source types are
233 available in each domain. Combined with the consistent practice of
234 never specifying an explicit domain when constructing your "My::DB"
235 objects, this allows the domain to be switched as needed, without
236 modifying any code in the actual application.
237
238 For example, imagine a mod_perl Apache web server environment running
239 application code that constructs its "My::DB" objects like this:
240
241 $main_db = My::DB->new('main');
242 $session_db = My::DB->new('session');
243
244 Now imagine a "startup.pl" file that contains the following:
245
246 # File: startup.pl
247 use My::DB;
248
249 if($ENV{'MYCORP_PRODUCTION_SERVER'})
250 {
251 My::DB->default_domain('production');
252 }
253 else
254 {
255 My::DB->default_domain('development');
256 }
257
258 This deliberate use of defaults combined with a healthy dose of
259 convention in your constructor calls can make it simple to move your
260 code from one environment to another without any changes beyond the
261 usual configuration management that must be done (e.g., for apache
262 configuration files).
263
264 The determination of the current environment can be done in many
265 different ways, of course. Checking an environment variable as shown
266 above is probably not the best way to do it, but it makes for a simple
267 example.
268
269 Another alternative is to use some sort of configuration/build
270 management system to generate the Apache configuration files from
271 templates. In that case, the templates could contain something like
272 this:
273
274 [% IF in_production %]
275 My::DB->default_domain('production');
276 [% ELSE %]
277 My::DB->default_domain('development');
278 [% END %]
279
280 This would leave only the single, appropriate call in the completed
281 "startup.pl" file.
282
283 Using your database objects
284 Before trying to use Rose::DB objects, it's important to understand the
285 primary goals of Rose::DB. The features are described in the Rose::DB
286 documentation, but there is one thing that is left unsaid. Although
287 Rose::DB is useful in isolation and provides many convenient methods
288 and abstractions, its primary purpose is to encapsulate database-
289 specific behaviors on behalf of Rose::DB::Object.
290
291 Of course, it could fill the same role for any Rose::DB::Object-like
292 module, and for any code that does the same kinds of things. If you
293 need to parse or format vendor-specific column values or want to use a
294 simple form of reference counting to keep track of shared database
295 handles, you may find Rose::DB useful.
296
297 The most common non-Rose::DB::Object-related use for Rose::DB is as a
298 way to get a DBI database handle without sweating the details of how
299 it's created or where it's connected. The previous sections of this
300 tutorial cover everything you need to know to set up Rose::DB to be
301 used in this capacity. Please be sure to read the Rose::DB
302 documentation as well, particularly the database handle life-cycle
303 management section.
304
306 The Rose development policy applies to this, and all "Rose::*" modules.
307 Please install Rose from CPAN and then run "perldoc Rose" for more
308 information.
309
311 Any Rose::DB questions or problems can be posted to the
312 Rose::DB::Object mailing list. (If the volume ever gets high enough,
313 I'll create a separate list for Rose::DB. But it isn't an issue right
314 now.) To subscribe to the list or view the archives, go here:
315
316 <http://groups.google.com/group/rose-db-object>
317
318 Although the mailing list is the preferred support mechanism, you can
319 also email the author (see below) or file bugs using the CPAN bug
320 tracking system:
321
322 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-DB>
323
324 There's also a wiki and other resources linked from the Rose project
325 home page:
326
327 <http://rosecode.org>
328
330 John C. Siracusa (siracusa@gmail.com)
331
333 Copyright (c) 2007 by John C. Siracusa. All rights reserved. This
334 program is free software; you can redistribute it and/or modify it
335 under the same terms as Perl itself.
336
337
338
339perl v5.32.0 2020-07-28 Rose::DB::Tutorial(3)