Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Minor Typo Fixes #3

Merged
merged 5 commits into from about 2 years ago

2 participants

chromatic castaway
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
48 chapters/01-Introduction.md
Source Rendered
@@ -31,7 +31,7 @@ Note that none of the choices are all-exclusive, you can use multiple types of d
31 31
32 32 ### Data::Dumper and Storable
33 33
34   -Data::Dumper[^datadumper] is a module for outputting a string representation of a Perl data structure. Its used mostly for debugging purposes. The data output by Data::Dumper can in theory be read back in, using eval. To output Perl data structures to disc and read them back in, its reccommended to use the Storable[^storable] standard module. Storable provides 'nstore' and 'retrieve' functions that will save a structure to a file and reload it.
  34 +Data::Dumper[^datadumper] is a module for outputting a string representation of a Perl data structure. It's used mostly for debugging purposes. The data output by Data::Dumper can in theory be read back in, using eval. To output Perl data structures to disk and read them back in, it's recommended to use the Storable[^storable] standard module. Storable provides 'nstore' and 'retrieve' functions that will save a structure to a file and reload it.
35 35
36 36 #### Pros
37 37
@@ -55,12 +55,12 @@ Data::Dumper[^datadumper] is a module for outputting a string representation of
55 55 use warnings;
56 56 use Storable;
57 57
58   - # Read previously stored data
  58 + # Read previously stored data
59 59 my $list = retrieve('/tmp/my-cached-data.dat');
60   -
  60 +
61 61 # Update cache
62 62 $list->{oranges} = 4;
63   -
  63 +
64 64 # Save new cache
65 65 nstore($list, '/tmp/my-cached-data.dat');
66 66
@@ -91,17 +91,17 @@ CPAN[^CPAN] has modules such as XML::Simple[^xmlsimple], JSON[^json], Text::xSV[
91 91
92 92 use strict;
93 93 use warnings;
94   -
  94 +
95 95 use XML::Simple;
96   -
  96 +
97 97 my $xml = '<some><format from="another">system</format></some>';
98 98 my $perldata = XMLIn($xml);
99   -
  99 +
100 100 $perldata->{some}{format}{from} = 'this';
101 101
102 102 ### Binary formats
103 103
104   -Binary file formats are used for compact storage and faster access. Predefined binary formats include Images, such as JPEG or PNG formats, which can be read and written using the Imager[^imager] module. Music files are also stored in binary formats, CPAN provides also modules for manipulating MP3 tags, such as MP3::Tag[^mp3tag].
  104 +Binary file formats are used for compact storage and faster access. Predefined binary formats include Images, such as JPEG or PNG formats, which can be read and written using the Imager[^imager] module. Music files are also stored in binary formats. CPAN also provides modules for manipulating MP3 tags, such as MP3::Tag[^mp3tag].
105 105
106 106 #### Pros
107 107
@@ -123,20 +123,20 @@ Binary file formats are used for compact storage and faster access. Predefined b
123 123
124 124 use strict;
125 125 use warnings;
126   -
  126 +
127 127 use Image::ExifTool qw(:Public);
128   -
  128 +
129 129 my $exift = Image::ExifTool->new();
130 130 $exift->ExtractInfo('a.jpg');
131 131 my $orig_datetime = $exitf->GetValue('DateTimeOriginal');
132   -
  132 +
133 133 $exift->SetNewValue('Artist', 'Fred');
134 134 $exift->WriteInfo('a.jpg');
135 135
136 136
137 137 ### Relational Databases
138 138
139   -Databases are systems for storing structured data, in a pre-defined layout. The layout of the data is set up for a particular use or application and the database system (RDBMS[^RDBMS]) enforces the constraints on the data to keep it consistent. Databases are access in Perl using DBI[^DBI] and the driver for the chosen database, popular ones are the open source systems Postgres[^pg], MySQL[^mysql] and SQLite[^sqlite]. DBI also supports the big commercial databases such as Oracle[^oracle], DB2[^db2] and MS SQL Server[^mssql].
  139 +Databases are systems for storing structured data, in a pre-defined layout. The layout of the data is set up for a particular use or application and the database system (RDBMS[^RDBMS]) enforces the constraints on the data to keep it consistent. Databases are accessed in Perl using DBI[^DBI] and the driver for the chosen database, popular ones are the open source systems Postgres[^pg], MySQL[^mysql] and SQLite[^sqlite]. DBI also supports the big commercial databases such as Oracle[^oracle], DB2[^db2] and MS SQL Server[^mssql].
140 140
141 141 #### Pros
142 142
@@ -158,27 +158,27 @@ Databases are systems for storing structured data, in a pre-defined layout. The
158 158
159 159 use strict;
160 160 use warnings;
161   -
  161 +
162 162 use DBI;
163   -
  163 +
164 164 my $dbh = DBI->connect("dbi:SQLite:mydb.db");
165   -
  165 +
166 166 $dbh->do("CREATE TABLE users(id integer primary key, username varchar(50), password varchar(50)");
167   -
  167 +
168 168 my $sth_insert = $dbh->prepare("INSERT INTO users (username, password) VALUES(?, ?)");
169 169 $sth_insert->execute("castaway", "mypass");
170   -
  170 +
171 171 my $sth_select = $dbh->prepare("SELECT id, username, password FROM users");
172 172 $sth_select->execute();
173   -
  173 +
174 174 while (my $row = $sth_select->fetchrow_hashref) {
175 175 printf("id: %d, username: %s", $row->{id}, $row->{username});
176 176 }
177   -
  177 +
178 178
179 179 ### NoSQL systems
180 180
181   -NoSQL actually means "Not a traditional relational database", some do in fact use the SQL language or a subset of it. There are several subtypes of NoSQL systems, Key-Value storage, Document storage, Big-Table and Graph storage. Generally they are usable similarly to RDBMS', and provide more performance and ease of use, countered with less promise of consistency and transactions. CPAN provides modules for several popular NoSQL systems, MongoDB[^mongodb], CouchDB[^couchdb].
  181 +NoSQL actually means "Not a traditional relational database". Some NoSQL systems do in fact use the SQL language or a subset of it. There are several subtypes of NoSQL systems, Key-Value storage, Document storage, Big-Table and Graph storage. Generally they are usable similarly to RDBMS', and provide more performance and ease of use, countered with less promise of consistency and transactions. CPAN provides modules for several popular NoSQL systems, MongoDB[^mongodb], CouchDB[^couchdb].
182 182
183 183 #### Pros
184 184
@@ -188,7 +188,7 @@ NoSQL actually means "Not a traditional relational database", some do in fact us
188 188 #### Cons
189 189
190 190 * Less consistency, constraint support.
191   -* Transactions only supported in some system.
  191 +* Transactions only supported in some systems.
192 192
193 193 #### Useful for
194 194
@@ -205,11 +205,11 @@ NoSQL actually means "Not a traditional relational database", some do in fact us
205 205 my $collection = $database->bar;
206 206 my $id = $collection->insert({ some => 'data' });
207 207 my $data = $collection->find_one({ _id => $id });
208   -
  208 +
209 209 Why relational databases and DBIx::Class?
210 210 ------------------------------------------
211 211
212   -DBIx::Class was started back in 2005 as a "research project", or so the original author, Matt Trout, will claim if you ask him. At the time Class::DBI[^classdbi] was the module to use if you wanted to abstract your SQL into Perl speak. Some brave developers put some of the early DBIC releases into production code and that was that. Since then it as grown to be one of the larger Perl community projects, with many releases by many members of the community, and an even longer list of contributors.
  212 +DBIx::Class was started back in 2005 as a "research project", or so the original author, Matt Trout, will claim if you ask him. At the time Class::DBI[^classdbi] was the module to use if you wanted to abstract your SQL into Perl speak. Some brave developers put some of the early DBIC releases into production code and that was that. Since then it as grown to be one of the larger Perl community projects, with many releases by many members of the community, and an even longer list of contributors.
213 213
214 214 I started using DBIx::Class early on in 2006, I forget exactly why, possibly something to do with SQL::Translator. I stayed for the communal feel, the responsiveness of the team to answer questions and fix bugs. At some point I got named "Documentation Queen", as I actually like writing documentation, and seem to be good at marshalling other people to write some, when they find an issue or can't understand the existing docs.
215 215
@@ -229,7 +229,7 @@ The sources of the various exercises and even code snippets for this book can be
229 229 [^RDBMS]: Relational Database Management Systems - databases such as Oracle, DB2, MySQL, Postgres and MS SQL Server.
230 230 [^DML]: Data Manipulaton Language, the part of SQL which is used to add, change and remove data.
231 231 [^DDL]: Data Definition Language, SQL statements to define tables, indexes and views for the data storage.
232   -[^CPAN]: The [Comprehensive Perl Archive Network](http://pause.cpan.org)
  232 +[^CPAN]: The [Comprehensive Perl Archive Network](http://pause.cpan.org)
233 233 [^datadumper]: [](http://metacpan.org/module/Data::Dumper)
234 234 [^storage]: [](http://metacpan.org/module/Storable)
235 235 [^xmlsimple]: [](http://metacpan.org/module/XML::Simple)
52 chapters/02-Databases-design-and-layout.md
Source Rendered
@@ -29,14 +29,13 @@ Examples given in this chapter will work with the one-file database [SQLite](htt
29 29 Introduction
30 30 ------------
31 31
32   -Choosing to use a database is the first step, the next part is harder,
33   -how to arrange all the pieces of data you need into tables, to
34   -optimise the performance of inserting and retrieving data. There is no
35   -perfect answer, as it will always depend on the uses your application
36   -will make of it. We'll show some techniques on how to consider your
37   -data and its uses, and divide it into tables and related tables. We'll
38   -also touch on some formal definitions, and show some places to get
39   -some more help if you're still stuck.
  32 +Choosing to use a database is the first step. The next part is harder; you must
  33 +arrange all the pieces of data you need into tables, to optimise the
  34 +performance of inserting and retrieving data. There is no perfect design, as
  35 +the database will always depend on the uses your application will make of it.
  36 +We'll show some techniques on how to consider your data and its uses, and
  37 +divide it into tables and related tables. We'll also touch on some formal
  38 +definitions, and show some places to get some more help if you're still stuck.
40 39
41 40 We are using the example of writing a blogging software or website
42 41 throughout this book. This example is chosen as hopefully all readers
@@ -244,13 +243,13 @@ database file which will be created if it does not exist yet:
244 243
245 244 ## Separate non-related data, flag fields
246 245
247   -Joe's written two posts, and Fred wrote one, now Fred comes back and
248   -makes a comment on Joe's first post. We could store our comments in
249   -the posts table, and give them all the same fields as the posts,
250   -however we'd still need a way to decide which items were posts and not
251   -comments, so we don't accidentally display comments as full posts.
  246 +Joe's written two posts, and Fred wrote one. Now Fred comes back and makes a
  247 +comment on Joe's first post. We could store our comments in the posts table,
  248 +and give them all the same fields as the posts--however we'd still need a way
  249 +to decide which items were posts and not comments, so we don't accidentally
  250 +display comments as full posts.
252 251
253   -One way to do this is to add a flag field to the table, for example a
  252 +One way to do this is to add a flag field to the table, in this case a
254 253 boolean (true/false) field named `is_post`. Our comments also need to
255 254 link back to the posts they are a comment on, so we'll add the
256 255 `comment-on` field. For posts of course this is irrelevant, so we'll
@@ -279,7 +278,7 @@ code to calculate for example, the number of comments by each user, we
279 278 will also have to add a filter.
280 279
281 280 As a rule of thumb, if the majority of your queries on the data will
282   -need to specify the filter, then its better to just separate the
  281 +need to specify the filter, then it's better to separate the
283 282 comments into their own table instead.
284 283
285 284 +----+---------+-------+-----------------+--------+-------------+
@@ -312,15 +311,15 @@ as we don't think we'll need to summarise comments.
312 311 You'll notice that we haven't yet looked at what happens to the data
313 312 in the user table when we add comments. We have the `role` field which
314 313 identifies which roles each user has. The original idea was to list
315   -their roles for each article, `poster` or `commenter`, but we've lost
  314 +the roles for each article, `poster` or `commenter`, but we've lost
316 315 that by dumping it into the user table.
317 316
318   -Each user can have multiple roles on each post, to store this in our
319   -database, we need a "many to many" relation (many users to many
320   -roles). Rather than putting this in either the users or posts tables,
321   -we can create an extra table to join the two together. We can also
322   -store the roles themselves in their own table and link their id in as
323   -well, or just use the string values.
  317 +Each user can have multiple roles on each post. To store this in our database,
  318 +we need a "many to many" relation (a user can have many roles and a role can
  319 +belong to many users). Rather than putting this in either the users or posts
  320 +tables, we can create an extra table to join the two together. We can either
  321 +store the roles themselves in their own table and link their id in as well, or
  322 +just use the string values in lieu of foreign keys.
324 323
325 324 +---------+---------+-----------+
326 325 | user_id | post_id | role |
@@ -361,16 +360,15 @@ avoid it by declaring that the roles are a hierarchy, that is that all
361 360
362 361 ## SQL break, SELECT ... FROM
363 362
364   -Getting data from one table is straight-forward, we use a `SELECT`
  363 +Getting data from one table is straight-forward. We use a `SELECT`
365 364 statement, for example to get user joe's information:
366 365
367 366 SELECT id, name, username, password, email
368 367 FROM users
369 368 WHERE username = 'joeb';
370   -
371   -To get the data from multiple tables, for example a user and their
372   -posts, we need to use the `JOIN` keyword, and join the tables on the
373   -unique values we created.
  369 +
  370 +To get the data from multiple tables--for example a user and their
  371 +posts--we need to use the `JOIN` keyword to connect the tables with the keys which identify relationships between them.
374 372
375 373 SELECT id, name, username, password, email, posts.title, posts.content, posts.summary, posts.created
376 374 FROM users
44 chapters/03-Describing-database.md
Source Rendered
@@ -11,7 +11,7 @@ Chapter summary
11 11 This chapter describes how to create a set of Perl modules using
12 12 DBIx::Class that describe your database tables, indexes and
13 13 relationships. The examples used will be based on a made-up schema
14   -representing a blog, we will introduce basic User and Post tables.
  14 +representing a blog. We will introduce basic User and Post tables.
15 15
16 16 Pre-requisites
17 17 --------------
@@ -60,16 +60,16 @@ of classes are needed:
60 60 contain and request all other objects representing the database
61 61 content. The schema object is created with connection information for
62 62 the particular database it will be talking to. The class can be
63   -re=used to connect to a different instance of the database, with a
  63 +re-used to connect to a different instance of the database, with a
64 64 different connection string, if needed.
65 65
66 66 * A **Result class** should be defined for each table or view to be
67   -accessed, this is used by DBIx::Class to represent a row of results
  67 +accessed. this is used by DBIx::Class to represent a row of results
68 68 from a query done via that particular table or view. Methods acting on
69 69 a row of data can be added here.
70 70
71 71 Other types of classes can be used to extend the functionality of the
72   -schema, these will be introduced later.
  72 +schema. These will be introduced later.
73 73
74 74 <a name="#a-word-about-namespaces"></a>
75 75
@@ -102,7 +102,7 @@ singular, as it respresents a single result, or row of the query.
102 102 The Schema class
103 103 ----------------
104 104
105   -The basic Schema class is fairly simple, it needs to inherit from
  105 +The basic Schema class is fairly simple. It needs to inherit from
106 106 **DBIx::Class::Schema** and call a class method to load all the
107 107 associated Result classes.
108 108
@@ -115,13 +115,13 @@ associated Result classes.
115 115
116 116 1;
117 117
118   -`load_namespaces` does the actual work here, it finds and loads all
119   -the files found in the `Result` subnamespace of your schema, see [](chapter_03-a-word-about-module-namespaces) above. It can also be
120   -configured to use other namespaces, or load only a subset of the
121   -available classes, by explicitly listing them.
  118 +`load_namespaces` does the actual work here. It finds and loads all
  119 +the files found in the `Result` subnamespace of your schema (see [](chapter_03-a-word-about-module-namespaces) above). It can also be
  120 +configured to use other namespaces or load only a subset of the
  121 +available classes by explicitly listing them.
122 122
123 123 The loaded files are assumed to be actual **Result classes** (see
124   -below) if anything else is found in the subnamespace, the load will
  124 +below). If anything else is found in the subnamespace, the load will
125 125 complain and die.
126 126
127 127 The Result class
@@ -142,7 +142,7 @@ information about the schema, for example to iterate through the
142 142 known columns on a table.
143 143
144 144 Result classes are only needed for each data source you need to access
145   -in your application, you do not need to create one for every table and
  145 +in your application. You do not need to create one for every table and
146 146 view in the database.
147 147
148 148 Result classes should inherit from
@@ -228,25 +228,25 @@ Now you can add lines describing the columns in your table.
228 228
229 229 8. __PACKAGE__->add_columns(
230 230 9. id => {
231   - 10. data_type => 'integer',
  231 + 10. data_type => 'integer',
232 232 11. is_auto_increment => 1,
233 233 12. },
234 234 13. realname => {
235 235 14. data_type => 'varchar',
236   - 15. size => 255,
  236 + 15. size => 255,
237 237 16. },
238 238 17. username => {
239 239 18. data_type => 'varchar',
240   - 19. size => 255,
  240 + 19. size => 255,
241 241 20. },
242 242 21. password => {
243   - 22. data_type => 'varchar',
244   - 23. size => 255,
  243 + 22. data_type => 'varchar',
  244 + 23. size => 255,
245 245 24. inflate_passphrase => 'rfc2307',
246 246 25. },
247 247 26. email => {
248 248 27. data_type => 'varchar',
249   - 28. size => 255,
  249 + 28. size => 255,
250 250 29. },
251 251 30. );
252 252
@@ -256,11 +256,11 @@ Now you can add lines describing the columns in your table.
256 256 - Line 8
257 257
258 258 `add_columns` is called to define all the columns in your table that
259   -you wish to tell DBIx::Class about, you may leave out some of the
260   -table's columns if you wish.
  259 +you wish to tell DBIx::Class about. You may leave out some of the
  260 +table's columns if you wish.
261 261
262 262 The `add_columns` call can provide as much or little description of the
263   -columns as it likes, in its simplest form, it can contain just a list
  263 +columns as it likes. In its simplest form, it can contain just a list
264 264 of column names:
265 265
266 266 __PACKAGE__->add_columns(qw/id realname username password email/);
@@ -331,7 +331,7 @@ _relationship_ methods.
331 331
332 332 To describe a _one to many_ relationship we call the `has_many`
333 333 method. For this one, the `posts` table has a column named
334   -`user_id` that contains the _id_ of the `users` table.
  334 +`user_id` that contains the _id_ of a row in the `users` table.
335 335
336 336 The first argument, `posts`, is a name for the relationship, this is
337 337 used as an accessor to retrieve the related items. It is also used
@@ -349,7 +349,7 @@ on.
349 349 - Data types
350 350
351 351 The `data_type` field for each column in the `add_columns` is a free
352   -text field, it is only used by DBIx::Class when deploying (creating
  352 +text field. It is only used by DBIx::Class when deploying (creating
353 353 tables) the schema to a database. At that point `data_type` values
354 354 are converted to the appropriate type for your database by
355 355 [SQL::Translator](http://search.cpan.org/perldoc?SQL::Translator).
66 chapters/04-Creating-Reading-Updating-Deleting.md
Source Rendered
@@ -9,7 +9,7 @@ In this chapter we will show how to do basic database operations using your DBIx
9 9 Pre-requisites
10 10 --------------
11 11
12   -We will be giving code examples and comparing them to the SQL statements that they produce, you should have basic SQL knowledge to understand this chapter. The database we are using is provided as an SQL file to import into an [SQLite database](http://search.cpan.org/dist/DBD-SQLite) to get started. You should also have basic knowledge of object-oriented code and Perl classes.
  12 +We will be giving code examples and comparing them to the SQL statements that they produce. You should have basic SQL knowledge to understand this chapter. The database we are using is provided as an SQL file to import into an [SQLite database](http://search.cpan.org/dist/DBD-SQLite) to get started. You should also have basic knowledge of object-oriented code and Perl classes.
13 13
14 14 [Download code](http://dbix-class.org/book/code/chapter04.zip) / preparation?
15 15
@@ -24,7 +24,7 @@ All the database manipulation with DBIx::Class is done via one central Schema ob
24 24
25 25 my $schema = MyBlog::Schema->connect("dbi:SQLite:myblog.db");
26 26
27   -Keep the `$schema` object in scope, if it disappears, other DBIx::Class objects you have floating about will stop working.
  27 +Keep the `$schema` object in scope. If it disappears, other DBIx::Class objects you have floating about will stop working.
28 28
29 29 To pass a username and password for the database, just add the strings as extra arguments to `connect`, for example when using MySQL:
30 30
@@ -34,13 +34,13 @@ You can also pass various [DBI](http://metacpan.org/dist/DBI) connection paramet
34 34
35 35 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword", { quote_char => "`'", quote_sep => '.' });
36 36
37   -For more detailed information about all the available connection arguments, see the [connect_info documentation](http://search.cpan.org/perldoc?DBIx::Class::Storage::DBI)
  37 +For more detailed information about all the available connection arguments, see the [connect_info documentation](http://search.cpan.org/perldoc?DBIx::Class::Storage::DBI).
38 38
39 39 ## Accessing data, the empty query aka ResultSet
40 40
41   -To manipulate any data in your database, you first need to create a **ResultSet** object. A ResultSet is an object representing a potential query, it is used to store the conditions and joins needed to produce the SQL statement.
  41 +To manipulate any data in your database, you first need to create a **ResultSet** object. A ResultSet is an object representing a potential query. It represents the conditions and joins needed to produce the SQL statement.
42 42
43   -ResultSets can be fetched using the **Result class** names, for example the users table is in `User.pm`, to fetch its ResultSet, using the `resultset` method:
  43 +ResultSets can be fetched using the **Result class** names. For example, `User.pm` describes the `users` table. To fetch its ResultSet, using the `resultset` method:
44 44
45 45 my $users_rs = $schema->resultset('User');
46 46
@@ -89,14 +89,14 @@ To see what's going on, set the shell environment variable [^DBIC_TRACE] to a tr
89 89 NB: The `?` symbols are placeholders, the actual values will be quoted according to your database rules, and passed in.
90 90
91 91 As the `id` column was defined as being `is_auto_increment` we haven't
92   -supplied that value at all, the database will fill it in, and the
  92 +supplied that value at all. the database will fill it in, and the
93 93 `insert` call will fetch the value and store it in our `$fred`
94 94 object. It will also do this for other database-supplied fields if
95 95 defined as `retrieve_on_insert` in `add_columns`.
96 96
97 97 ### Your turn, create a User and verify with a test
98 98
99   -Now that's all hopefully made sense, time for a bit of Test-Driven-Development.
  99 +Now that's all hopefully made sense, it's time for a bit of Test-Driven-Development.
100 100
101 101 This is a short Perl test that will check that a user, and only one user, with the `email` of **alice@bloggs.com** exists in the database. You can type it up into a file named **check-alice-exists.t** in t/ directory, or unpack it from the provided tarball.
102 102
@@ -233,7 +233,7 @@ Lookup the solution if you get stuck.
233 233
234 234 ## Finding and changing a User's data later on
235 235
236   -We've entered several users into our database, now it would be useful
  236 +We've entered several users into our database. Now it would be useful
237 237 to be able to find them again, and log them in or update their
238 238 data. If you've been paying close attention to the tests we've used to
239 239 check your progress, you'll notice the `find` ResultSet method.
@@ -243,10 +243,10 @@ primary key or a known unique set of columns. These are both named in
243 243 the **Result Class** using `set_primary_key` and
244 244 `add_unique_constraint` respectively. By default `find` will try all
245 245 the given columns against the primary and unique keys to find the best
246   -match, this will not work well if no key columns are present.
  246 +match. This will not work well if no key columns are present.
247 247
248 248 To login, the user will give you their username and password data, to
249   -verify against a securely stored password, we need to first find the
  249 +verify against a securely stored password. We need to first find the
250 250 User object, then test against the password.
251 251
252 252 Enough chatter, here's some code:
@@ -271,8 +271,7 @@ Now that we've verified that fred is who he says he is, we can allow
271 271 him to update his email address or change his password, and store
272 272 those changes.
273 273
274   -This example uses a small console based programm to illustrate, as
275   -there wasn't room for an entire Web application.
  274 +This example uses a small console based program to illustrate. (Performing this behavior on DBIx::Class objects demonstrates how you can share a database layer between a command-line program and a web application, for example.)
276 275
277 276 my $username = prompt('x', 'Your username', 'Enter your username', '');
278 277
@@ -306,12 +305,12 @@ We've entered some single unrelated rows into the database, now we'll
306 305 look at how the relations work. In DBIx::Class *related* data means
307 306 data stored across multiple tables which is related in some way.
308 307
309   -[%# yes we know this is at odds to how "real" relations in RDBMS' are described.. %]
  308 +[%# yes we know this is at odds to how "real" relations in RDBMS' are described. %]
310 309
311   -In the `User` class we defined a `has_many` relationship to the `Post`
  310 +The `User` class we defined a `has_many` relationship to the `Post`
312 311 class, indicating that a user can create multiple posts. In the
313 312 database the `user_id` field stores the id of the Post-owning user
314   -against each Post row.
  313 +for each Post row.
315 314
316 315 Once we have a Row object representing a user, we can create related
317 316 Post entries without having to spell out the relationship:
@@ -322,7 +321,7 @@ Post entries without having to spell out the relationship:
322 321 });
323 322
324 323 This will automatically pick up the `id` value from the `$fred`
325   -object, and insert it into the `user_id` column in the Posts
  324 +object and insert it into the `user_id` column in the Posts
326 325 table. The `$fred` object must be a User row that exists in the
327 326 database.
328 327
@@ -333,7 +332,7 @@ In true perlish TIMTOWTDI spirit, this can also be written as:
333 332 post => 'A very short post',
334 333 });
335 334
336   -The `posts` method is created by our `has_many` relation, it will
  335 +The `posts` method is created by our `has_many` relation. It will
337 336 return a **DBIx::Class::ResultSet** object with a condition for all
338 337 the one or more related Post entries.
339 338
@@ -374,7 +373,7 @@ a list of alternate conditions:
374 373 realname => [ map { { '-like' => "%$_%"} } @badwords ],
375 374 });
376 375
377   -The result is a ResultSet which contains the condition we want, now we
  376 +The result is a ResultSet which contains the condition we want. Now we
378 377 can update all the rows at once by applying `update` to the ResultSet.
379 378
380 379 $badusers_rs->update({ realname => 'XXXX' });
@@ -410,7 +409,7 @@ behaviour, set up the relationship with `cascade_delete` set to 0:
410 409 32. __PACKAGE__->has_many('posts', 'MyBlog::Schema::Result::Post', 'user_id', { cascade_delete => 0 });
411 410
412 411
413   -To remove a multiple rows at once, create a resultset object that matches the
  412 +To remove multiple rows at once, create a resultset object that matches the
414 413 rows to remove, and call the `delete` method on it:
415 414
416 415 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
@@ -429,7 +428,7 @@ true value to indicate the data is no longer in use.
429 428
430 429 ## Advanced create/update/delete
431 430
432   -Now we go a bit wild, there are a bunch of useful methods and
  431 +Now we go a bit wild. There are a bunch of useful methods and
433 432 techniques which simplify your code by combining methods
434 433 we've already looked at in this chapter. I'll give a description and
435 434 usage hint for each one, then we'll do some more tests.
@@ -457,14 +456,14 @@ For example, you can do this:
457 456 email => 'john.smith@example.com',
458 457
459 458 posts => [
460   - {
461   - title => "John's first post",
462   - post => 'Tap, tap, is this thing on?',
463   - },
464   - {
465   - title => "John's second post",
466   - post => "Anybody out there?",
467   - }
  459 + {
  460 + title => "John's first post",
  461 + post => 'Tap, tap, is this thing on?',
  462 + },
  463 + {
  464 + title => "John's second post",
  465 + post => "Anybody out there?",
  466 + }
468 467 ],
469 468 });
470 469
@@ -489,7 +488,7 @@ You can also do this:
489 488 my $fred = $users_rs->find({ username => 'fred' });
490 489 my $posts_rs = $schema->resultset('Post');
491 490
492   - $postss_rs->create({
  491 + $posts_rs->create({
493 492 title => "John's first post",
494 493 post => 'Tap, tap, is this thing on?',
495 494 user => $fred,
@@ -506,8 +505,7 @@ database, if it has not yet been).
506 505
507 506 We can already `find` single rows based on their unique values, and
508 507 `create` new rows. If we try to create a new row using data that
509   -already matches unique values in the database, we will get an error,
510   -let's test:
  508 +already matches unique values in the database, we will get an error:
511 509
512 510 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
513 511 my $users_rs = $schema->resultset('User');
@@ -536,7 +534,7 @@ let's test:
536 534 Oops! For usernames, this is probably what we want to happen, instead
537 535 of overwriting the existing user, it just fails. It would be more
538 536 useful if it instead returned the existing user row, so that we can
539   -use it. For example to send the user a password reset email.
  537 +use it--for example, to send the user a password reset email.
540 538
541 539 `find_or_create` will start by running a `find` based on the primary
542 540 or unique values passed in the data, if it finds a match it will
@@ -570,8 +568,8 @@ new row. If we repeat our exercise using find_or_create:
570 568 print $fred->id;
571 569 print $fred2->id;
572 570
573   -Notice that `$fred` and `$fred2` have the same primary key (id), they
574   -are representing the same row. This technique only works when you are
  571 +Notice that `$fred` and `$fred2` have the same primary key (id); they
  572 +represent the same row. This technique only works when you are
575 573 passing in values for the unique or primary keys.
576 574
577 575 NOTE: Using find_or_create can produce race conditions, as it does two
67 chapters/05-Further-queries-and-helpers.md
Source Rendered
@@ -43,11 +43,11 @@ the `-like` comparison operator.
43 43
44 44 `LIKE` is an SQL keyword used to compare data against simple wildcard
45 45 matching. `%` matches any number of characters, `_` matches a single
46   -character. LIKE is defined as being case-insensitive in the SQL
  46 +character. While LIKE is defined as being case-insensitive in the SQL
47 47 standard, it is not implemented as such in all databases (PostgreSQL
48   -is one example, it provides the LIKE and ILIKE keywords).
  48 +for example, provides the LIKE and ILIKE keywords).
49 49
50   -The two arguments to `search` are a set of conditions, and a set of
  50 +The two arguments to `search` are a set of conditions and a set of
51 51 attributes. The conditions supply the filters to apply to the data,
52 52 the attributes add grouping, sorting and joining and more.
53 53
@@ -81,7 +81,7 @@ ResultSet using the `next` method.
81 81 A default `search` will fetch all the columns defined in the
82 82 ResultSource that we're using for the search. Note that the
83 83 ResultSource itself does not need to define all the columns in a
84   -database table, if you don't need to use some of them in your
  84 +database table. If you don't need to use some of them in your
85 85 application at all, you can leave them out of the Schema.
86 86
87 87 You may want to reduce the set of columns fetched from the database,
@@ -117,7 +117,7 @@ To get the SQL:
117 117
118 118 The SQL `SELECT` clause can contain many other things, for example
119 119 functions such as `length`. To output a function and its arguments,
120   -use a hashref in the `columns` attribute, we can also add new columns
  120 +use a hashref in the `columns` attribute. You can also add new columns
121 121 to the default set using the `+columns` attribute.
122 122
123 123 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
@@ -125,7 +125,7 @@ to the default set using the `+columns` attribute.
125 125 my $users_rs = $schema->resultset('User');
126 126 my $users_plus_emaillen_rs = $users_rs->search({
127 127 }, {
128   - '+columns' => [ { 'userlen' => { length => 'username' } }],
  128 + '+columns' => [ { 'emaillen' => { length => 'email' } }],
129 129 });
130 130
131 131 Which produces the SQL:
@@ -162,14 +162,14 @@ data values in the database, or manipulations of those values. The
162 162 type of sorting we get depends on the data types in the columns. We
163 163 can fetch all our users ordered by their usernames for display:
164 164
165   -The `order_by` attribute is used to output the SQL keywords `ORDER BY`.
  165 +The `order_by` attribute corresponds to the SQL keyword `ORDER BY`.
166 166 Sorting can be done either ascending, with `-asc`, or descending
167 167 with `-desc`.
168 168
169 169 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
170 170
171 171 my $users_rs = $schema->resultset('User')->search({
172   - }, {
  172 + },
173 173 order_by => { '-desc' => ['me.username'] }
174 174 });
175 175
@@ -179,16 +179,15 @@ We get the SQL:
179 179 FROM users me
180 180 ORDER BY me.username DESC
181 181
182   -The results from our loop over the results are now sorted by username,
183   -no need to sort further in Perl or your templating system.
  182 +The results from our loop over the results are now sorted by username.
  183 +There's no need to sort further in Perl or your templating system.
184 184
185   -Now that we have rows in a known order, we can also reduce the set of
186   -results to a top ten, or to a page worth of results, so that we only
187   -fetch data we'll actually use. There are unfortunately many different
188   -implementations of ways to reduce the number of rows returned by an
189   -SQL query. Luckily DBIx::Class abstracts these away for you, providing
190   -a single `rows` attribute that is converted to the correct keyword
191   -when the query is run.
  185 +Now that we have rows in a known order, we can also reduce the set of results
  186 +to a top ten, or to a page worth of results, so that we only fetch data we'll
  187 +actually use. There are unfortunately many different database-specific
  188 +implementations of ways to reduce the number of rows returned by an SQL query.
  189 +Luckily DBIx::Class abstracts these away for you, providing a single `rows`
  190 +attribute that is converted to the correct keyword when the query is run.
192 191
193 192 The first 'page' of 10 usernames to display:
194 193
@@ -208,12 +207,12 @@ On SQLite and MySQL we get the SQL:
208 207 LIMIT 10
209 208
210 209 Which returns a maximum of 10 rows. If the unlimited query would
211   -return less than 10 rows, then we just get those, no error is thrown.
  210 +return fewer than 10 rows, then we just get those. No error is thrown.
212 211
213   -SQL even provides a way to return a specified set of results from
  212 +SQL even provides a way to return a specified subset of results from
214 213 within the entire set, so we can fetch a second page of results
215 214 precisely. DBIx::Class implements this by providing the `page`
216   -attribute to select which page of results to return, this defaults to
  215 +attribute to select which page of results to return. This defaults to
217 216 1 if not supplied.
218 217
219 218 The second 'page' of 10 usernames to display:
@@ -333,14 +332,14 @@ This test can be found in the file **ordered_posts.t**.
333 332 ## Joining, Aggregating and Grouping on related data
334 333
335 334 We've seen how to create related rows, either singly or together with
336   -other data, now we can look at how to query or fetch all that data
  335 +other data. Now we can look at how to query or fetch all that data
337 336 without making multiple trips to the database. The SQL keyword `JOIN`
338 337 can be produced using the attribute `join` and providing it a list of
339 338 related resultsources to join on. The joined tables can be accessed in
340 339 the search conditions and other clauses, using the name of the
341 340 relationship.
342 341
343   -Here is a more concrete example, we can fetch a list of our users,
  342 +Here is a more concrete example. We can fetch a list of our users
344 343 together with the number of posts that they have written.
345 344
346 345 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
@@ -367,7 +366,7 @@ columns, so we want a count of unique posts.id values per user. The
367 366
368 367 NB: The SQL standard says that GROUP BY should include all the queried
369 368 (`SELECT`ed) columns which are not being aggregated. Some databases
370   -enforce this, some, such as MySQL, do not by default.
  369 +enforce this. Some, such as MySQL, do not by default.
371 370
372 371
373 372 ## Your turn, find the earliest post of each user
@@ -464,7 +463,7 @@ This test can be found in the file **earliest_posts.t**.
464 463
465 464 With [](chapter_05-joining-aggregating-and-grouping-on-related-data) and
466 465 various aggregation functions we can sum or count data across groups
467   -of rows, if we want to then filter the results again, for example to
  466 +of rows. If we want to filter the results again, for example to
468 467 get only the groups whose COUNT is greater than a certain value, we
469 468 need to use the SQL keyword `HAVING`. To differentiate, the `WHERE`
470 469 clause applies before the grouping, and the `HAVING` clause applies
@@ -485,10 +484,10 @@ So to return all users that have at least one post:
485 484 having => [ { 'post_count' => { '>=' => 1 } } ],
486 485 });
487 486
488   -Note that we've added the `-as` argument to our `post_count` column,
489   -this is required to output the SQL `AS` keyword, which is used to
490   -alias the result of a function call or calculation. The alias can then
491   -be used in subsequent clauses, such as the `HAVING` clause.
  487 +Note that we've added the `-as` argument to our `post_count` column. This is
  488 +required to output the SQL `AS` keyword, which aliases the result of a function
  489 +call or calculation. The alias can then be used in subsequent clauses, such as
  490 +the `HAVING` clause.
492 491
493 492 We get the SQL:
494 493
@@ -728,7 +727,7 @@ To use the `UNION`, `INTERSECT` and `EXCEPT` keywords, install the
728 727 [DBIx::Class::Helpers module from CPAN](http://metacpan.org/module/DBIx::Class::Helpers).
729 728
730 729 Using these constructs we can glue together the results of arbitrary
731   -resultsets, for example of if we want to allow users to search for
  730 +resultsets. For example, if we want to allow users to search for
732 731 either usernames or post titles (or contents), we can UNION together
733 732 several resultsets. Take care to select the same number of columns in
734 733 the resultsets.
@@ -749,7 +748,7 @@ component. Put this in the `MyBlog/Schema/ResultSet/User.pm` file:
749 748
750 749 1;
751 750
752   -Now we can use the Helper methods provided, first, create some
  751 +Now we can use the Helper methods provided. First, create some
753 752 resultsets to query each of the fields we wish to search on:
754 753
755 754 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
@@ -777,7 +776,7 @@ resultsets to query each of the fields we wish to search on:
777 776 }
778 777 );
779 778
780   - my $realname_rs= $users_rs->search(
  779 + my $realname_rs = $users_rs->search(
781 780 {},
782 781 {
783 782 'columns' => [ 'id', { search => \'realname as search'}, { tablename => \'"User" as tablename'}],
@@ -842,7 +841,7 @@ The SQL we get looks like this:
842 841 Which is executed with the placeholders set to: ('fred')
843 842
844 843 `intersect` and `except` can be used in exactly the same way, and
845   -produce respectively a set of results which exists in all the querys
  844 +produce respectively a set of results which exists in all the queries
846 845 given, and a set of results that contains all rows in the first query,
847 846 without any that appear in the subsequent queries.
848 847
@@ -1162,12 +1161,12 @@ If any of these fail, the entire set of statements is automatically
1162 1161 reverted using the `ROLLBACK` statement.
1163 1162
1164 1163 It's possible that you can't collect all the code you need to run in a
1165   -transaction, into the same place in your code. In this case there are
  1164 +transaction in the same place in your code. In this case there are
1166 1165 also the bare bones methods `txn_begin` and `txn_commit` on the
1167 1166 `Schema` object, which will independently start and end a
1168 1167 transaction. Another alternative is the `txn_scope_guard` method which
1169 1168 will return a `$guard` object. This will issue a rollback if it goes
1170   -out of scope, otherwise it can be used to issue a `commit` statement.
  1169 +out of scope. Otherwise it can be used to issue a `commit` statement.
1171 1170
1172 1171 my $schema = MyBlog::Schema->connect("dbi:mysql:dbname=myblog", "myuser", "mypassword");
1173 1172 my $users_rs = $schema->resultset('User');

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.