3 Catalyst::Manual::Tutorial::Appendices - Catalyst Tutorial - Part 10: Appendices
8 This is B<Part 10 of 10> for the Catalyst tutorial.
10 L<Tutorial Overview|Catalyst::Manual::Tutorial>
16 L<Introduction|Catalyst::Manual::Tutorial::Intro>
20 L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
24 L<More Catalyst Basics|Catalyst::Manual::Tutorial::MoreCatalystBasics>
28 L<Basic CRUD|Catalyst::Manual::Tutorial::BasicCRUD>
32 L<Authentication|Catalyst::Manual::Tutorial::Authentication>
36 L<Authorization|Catalyst::Manual::Tutorial::Authorization>
40 L<Debugging|Catalyst::Manual::Tutorial::Debugging>
44 L<Testing|Catalyst::Manual::Tutorial::Testing>
48 L<Advanced CRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
59 This part of the tutorial provides supporting information relevant to
60 the Catalyst tutorial.
63 =head1 APPENDIX 1: CUT AND PASTE FOR POD-BASED EXAMPLES
65 You may notice that Pod indents example code with four spaces. This
66 section provides some quick advice to "un-indent" this text in common
69 =head2 "Un-indenting" with Vi/Vim
71 When cutting and pasting multi-line text from Pod-based documents, the
72 following vi/vim regexs can be helpful to "un-indent" the inserted text
73 (do NOT type the quotes, they are only included to show spaces in the
74 regex patterns). I<Note that all 3 of the regexs end in 4 spaces>:
82 Removes four leading spaces from the entire file (from the first line,
83 C<0>, to the last line, C<$>).
89 A shortcut for the previous item (C<%> specifies the entire file; so
90 this removes four leading spaces from every line).
96 Removes the first four spaces from the line the cursor is on at the time
97 the regex command is executed (".") to the last line of the file.
103 Removes four leading space from the current line through line 44
104 (obviously adjust the C<44> to the appropriate value in your example).
108 =head2 "Un-indenting" with Emacs
110 Although there author has not used emacs for many years (apologies to
111 the emacs fans out there), here is a quick hint to get you started. To
112 replace the leading spaces of every line in a file, use:
114 M-x replace-regexp<RET>
115 Replace regexp: ^ <RET>
118 All of that will occur on the single line at the bottom of your screen.
119 Note that "<RET>" represents the return key/enter. Also, there are
120 four spaces after the "^" on the "Replace regexp:" line and no spaces
121 entered on the last line.
123 You can limit the replacement operation by selecting text first (depending
124 on your version of emacs, you can either use the mouse or experiment with
125 commands such as C<C-SPC> to set the mark at the cursor location and
126 C<C-E<lt>> and C<C-E<gt>> to set the mark at the beginning and end of the
130 =head1 APPENDIX 2: USING MYSQL AND POSTGRESQL
132 The main database used in this tutorial is the very simple yet powerful
133 SQLite. This section provides information that can be used to "convert"
134 the tutorial to use MySQL and PostgreSQL. However, note that part of
135 the beauty of the MVC architecture is that very little database-specific
136 code is spread throughout the system (at least when MVC is "done
137 right"). Consequently, converting from one database to another is
138 relatively painless with most Catalyst applications. In general, you
139 just need to adapt the schema definition C<.sql> file you use to
140 initialize your database and adjust a few configuration parameters.
142 Also note that the purpose of the data definition statements for this
143 section are not designed to take maximum advantage of the various
144 features in each database for issues such as referential integrity and
145 field types/constraints.
149 Use the following steps to adapt the tutorial to MySQL. Thanks to Jim
156 Part 2: Catalyst Basics
162 Install the required software:
168 The MySQL database server and client utility.
172 The Perl C<DBD::MySQL> module
176 For CentOS users (see
177 L<Catalyst::Manual::Installation::CentOS4|Catalyst::Manual::Installation::CentOS4>),
178 you can use the following commands to install the software and start the MySQL
181 yum -y install mysql mysql-server
186 Create the database and set the permissions:
189 Welcome to the MySQL monitor. Commands end with ; or \g.
190 Your MySQL connection id is 2 to server version: 4.1.20
192 Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
194 mysql> create database myapp;
195 Query OK, 1 row affected (0.01 sec)
197 mysql> grant all on myapp.* to tutorial@'localhost';
198 Query OK, 0 rows affected (0.00 sec)
200 mysql> flush privileges;
201 Query OK, 0 rows affected (0.00 sec)
208 Create the C<.sql> file and load the data:
214 Open the C<myapp01_mysql.sql> in your editor and enter:
217 -- Create a very simple database to hold book and author information
219 DROP TABLE IF EXISTS books;
220 DROP TABLE IF EXISTS book_authors;
221 DROP TABLE IF EXISTS authors;
223 id INT(11) PRIMARY KEY AUTO_INCREMENT,
227 -- 'book_authors' is a many-to-many join table between books & authors
228 CREATE TABLE book_authors (
231 PRIMARY KEY (book_id, author_id)
233 CREATE TABLE authors (
234 id INT(11) PRIMARY KEY AUTO_INCREMENT,
239 --- Load some sample data
241 INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5);
242 INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5);
243 INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4);
244 INSERT INTO books VALUES (4, 'Perl Cookbook', 5);
245 INSERT INTO books VALUES (5, 'Designing with Web Standards', 5);
246 INSERT INTO authors VALUES (1, 'Greg', 'Bastien');
247 INSERT INTO authors VALUES (2, 'Sara', 'Nasseh');
248 INSERT INTO authors VALUES (3, 'Christian', 'Degu');
249 INSERT INTO authors VALUES (4, 'Richard', 'Stevens');
250 INSERT INTO authors VALUES (5, 'Douglas', 'Comer');
251 INSERT INTO authors VALUES (6, 'Tom', 'Christiansen');
252 INSERT INTO authors VALUES (7, ' Nathan', 'Torkington');
253 INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman');
254 INSERT INTO book_authors VALUES (1, 1);
255 INSERT INTO book_authors VALUES (1, 2);
256 INSERT INTO book_authors VALUES (1, 3);
257 INSERT INTO book_authors VALUES (2, 4);
258 INSERT INTO book_authors VALUES (3, 5);
259 INSERT INTO book_authors VALUES (4, 6);
260 INSERT INTO book_authors VALUES (4, 7);
261 INSERT INTO book_authors VALUES (5, 8);
267 mysql -ututorial myapp < myapp01_mysql.sql
271 Make sure the data loaded correctly:
273 $ mysql -ututorial myapp
274 Reading table information for completion of table and column names
275 You can turn off this feature to get a quicker startup with -A
277 Welcome to the MySQL monitor. Commands end with ; or \g.
278 Your MySQL connection id is 4 to server version: 4.1.20
280 Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
290 3 rows in set (0.00 sec)
292 mysql> select * from books;
293 +----+------------------------------------+--------+
294 | id | title | rating |
295 +----+------------------------------------+--------+
296 | 1 | CCSP SNRS Exam Certification Guide | 5 |
297 | 2 | TCP/IP Illustrated, Volume 1 | 5 |
298 | 3 | Internetworking with TCP/IP Vol.1 | 4 |
299 | 4 | Perl Cookbook | 5 |
300 | 5 | Designing with Web Standards | 5 |
301 +----+------------------------------------+--------+
302 5 rows in set (0.00 sec)
316 Delete the existing model:
318 rm lib/MyApp/Model/MyAppDB.pm
322 Regenerate the model using the Catalyst "_create.pl" script:
324 script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB dbi:mysql:myapp 'tutorial' '' '{ AutoCommit => 1 }'
332 Part 4: Authentication
338 Create the C<.sql> file for the user/roles data:
340 Open C<myapp02_mysql.sql> in your editor and enter:
343 -- Add users and roles tables, along with a many-to-many join table
346 id INT(11) PRIMARY KEY,
355 id INTEGER PRIMARY KEY,
358 CREATE TABLE user_roles (
361 PRIMARY KEY (user_id, role_id)
364 -- Load up some initial test data
366 INSERT INTO users VALUES (1, 'test01', 'mypass', 't01@na.com', 'Joe', 'Blow', 1);
367 INSERT INTO users VALUES (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe', 1);
368 INSERT INTO users VALUES (3, 'test03', 'mypass', 't03@na.com', 'No', 'Go', 0);
369 INSERT INTO roles VALUES (1, 'user');
370 INSERT INTO roles VALUES (2, 'admin');
371 INSERT INTO user_roles VALUES (1, 1);
372 INSERT INTO user_roles VALUES (1, 2);
373 INSERT INTO user_roles VALUES (2, 1);
374 INSERT INTO user_roles VALUES (3, 1);
378 Load the user/roles data:
380 mysql -ututorial myapp < myapp02_mysql.sql
384 Create the C<.sql> file for the hashed password data:
386 Open C<myapp03_mysql.sql> in your editor and enter:
389 -- Convert passwords to SHA-1 hashes
391 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 1;
392 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 2;
393 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 3;
397 Load the user/roles data:
399 mysql -ututorial myapp < myapp03_mysql.sql
407 Use the following steps to adapt the tutorial to PostgreSQL. Thanks to
408 Louis Moore for the help who was in turn helped by Marcello Romani and
415 Part 2: Catalyst Basics
421 Install the required software:
427 The PostgreSQL database server and client.
431 The Perl C<DBD::Pg> module
437 Create the database and a user for the database
439 $ createuser -P catmyapp
440 Enter password for new role: <catalyst>
441 Enter it again: <catalyst>
442 Shall the new role be a superuser? (y/n) n
443 Shall the new role be allowed to create databases? (y/n) n
444 Shall the new role be allowed to create more new roles? (y/n) n
446 $ createdb -O catmyapp mycatapp
451 Create the C<.sql> file and load the data:
457 Open the C<myapp01_psql.sql> in your editor and enter:
461 -- Create a very simple database to hold book and author information
463 -- The sequence is how we get a unique id in PostgreSQL
465 CREATE SEQUENCE books_seq START 5 ;
466 SELECT nextval ('books_seq');
469 id INTEGER PRIMARY KEY DEFAULT nextval('books_seq'),
474 -- 'book_authors' is a many-to-many join table between books & authors
475 CREATE TABLE book_authors (
478 PRIMARY KEY (book_id, author_id)
481 CREATE SEQUENCE authors_seq START 8 ;
482 SELECT nextval ('authors_seq');
484 CREATE TABLE authors (
485 id INTEGER PRIMARY KEY DEFAULT nextval('authors_seq'),
490 --- Load some sample data
492 INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5);
493 INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5);
494 INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4);
495 INSERT INTO books VALUES (4, 'Perl Cookbook', 5);
496 INSERT INTO books VALUES (5, 'Designing with Web Standards', 5);
497 INSERT INTO authors VALUES (1, 'Greg', 'Bastien');
498 INSERT INTO authors VALUES (2, 'Sara', 'Nasseh');
499 INSERT INTO authors VALUES (3, 'Christian', 'Degu');
500 INSERT INTO authors VALUES (4, 'Richard', 'Stevens');
501 INSERT INTO authors VALUES (5, 'Douglas', 'Comer');
502 INSERT INTO authors VALUES (6, 'Tom', 'Christiansen');
503 INSERT INTO authors VALUES (7, 'Nathan', 'Torkington');
504 INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman');
505 INSERT INTO book_authors VALUES (1, 1);
506 INSERT INTO book_authors VALUES (1, 2);
507 INSERT INTO book_authors VALUES (1, 3);
508 INSERT INTO book_authors VALUES (2, 4);
509 INSERT INTO book_authors VALUES (3, 5);
510 INSERT INTO book_authors VALUES (4, 6);
511 INSERT INTO book_authors VALUES (4, 7);
512 INSERT INTO book_authors VALUES (5, 8);
518 $ psql -U catmyapp -W mycatapp
519 Password for user catmyapp: catalyst
520 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
522 Type: \copyright for distribution terms
523 \h for help with SQL commands
524 \? for help with psql commands
525 \g or terminate with semicolon to execute query
528 mycatapp=> \i myapp01_psql.sql
536 psql:myapp01_psql.sql:11: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "books_pkey" for table "books"
538 psql:myapp01_psql.sql:19: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "book_authors_pkey" for table
547 psql:myapp01_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "authors_pkey" for table "authors"
557 Make sure the data loaded correctly:
561 Schema | Name | Type | Owner
562 --------+--------------+-------+----------
563 public | authors | table | catmyapp
564 public | book_authors | table | catmyapp
565 public | books | table | catmyapp
568 mycatapp=> select * from books;
570 ----+------------------------------------+--------
571 1 | CCSP SNRS Exam Certification Guide | 5
572 2 | TCP/IP Illustrated, Volume 1 | 5
573 3 | Internetworking with TCP/IP Vol.1 | 4
574 4 | Perl Cookbook | 5
575 5 | Designing with Web Standards | 5
584 After the steps where you:
588 create lib/MyAppDB.pm
590 create lib/MyAppDB/Book.pm
592 create lib/MyAppDB/Author.pm
594 create lib/MyAppDB/BookAuthor.pm
599 Generate the model using the Catalyst "_create.pl" script:
601 script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB 'dbi:Pg:dbname=mycatapp' 'catmyapp' 'catalyst' '{ AutoCommit => 1 }'
608 Part 4: Authentication
614 Create the C<.sql> file for the user/roles data:
616 Open C<myapp02_psql.sql> in your editor and enter:
619 -- Add users and roles tables, along with a many-to-many join table
622 CREATE SEQUENCE users_seq START 3 ;
623 SELECT nextval ('users_seq');
626 id INTEGER PRIMARY KEY DEFAULT nextval('users_seq'),
635 CREATE SEQUENCE roles_seq START 2 ;
636 SELECT nextval ('roles_seq');
639 id INTEGER PRIMARY KEY DEFAULT nextval('roles_seq'),
643 CREATE TABLE user_roles (
646 PRIMARY KEY (user_id, role_id)
650 -- Load up some initial test data
652 INSERT INTO users VALUES (1, 'test01', 'mypass', 't01@na.com', 'Joe', 'Blow', 1);
653 INSERT INTO users VALUES (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe', 1);
654 INSERT INTO users VALUES (3, 'test03', 'mypass', 't03@na.com', 'No', 'Go', 0);
655 INSERT INTO roles VALUES (1, 'user');
656 INSERT INTO roles VALUES (2, 'admin');
657 INSERT INTO user_roles VALUES (1, 1);
658 INSERT INTO user_roles VALUES (1, 2);
659 INSERT INTO user_roles VALUES (2, 1);
660 INSERT INTO user_roles VALUES (3, 1);
666 $ psql -U catmyapp -W mycatapp
667 Password for user catmyapp: catalyst
668 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
670 Type: \copyright for distribution terms
671 \h for help with SQL commands
672 \? for help with psql commands
673 \g or terminate with semicolon to execute query
676 mycatapp=> \i myapp02_psql.sql
684 psql:myapp02_psql.sql:16: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users"
692 psql:myapp02_psql.sql:24: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "roles_pkey" for table "roles"
694 psql:myapp02_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "user_roles_pkey" for table "user_roles"
707 mycatapp=> select * from users;
708 id | username | password | email_address | first_name | last_name | active
709 ----+----------+----------+---------------+------------+-----------+--------
710 1 | test01 | mypass | t01@na.com | Joe | Blow | 1
711 2 | test02 | mypass | t02@na.com | Jane | Doe | 1
712 3 | test03 | mypass | t03@na.com | No | Go | 0
718 Create the C<.sql> file for the hashed password data:
720 Open C<myapp03_psql.sql> in your editor and enter:
723 -- Convert passwords to SHA-1 hashes
725 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 1;
726 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 2;
727 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 3;
733 $ psql -U catmyapp -W mycatapp
734 Password for user catmyapp:
735 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
737 Type: \copyright for distribution terms
738 \h for help with SQL commands
739 \? for help with psql commands
740 \g or terminate with semicolon to execute query
743 mycatapp=> \i myapp03_psql.sql
755 =head1 APPENDIX 3: IMPROVED HASHING SCRIPT
757 Here is an improved SHA-1 hashing script from Gavin Henry that does
758 not expose the passwords to "capture" on the command line.
761 #===============================================================================
765 # USAGE: ./enc_pass.pl
767 # DESCRIPTION: Encrypt a Password using SHA-1
773 # AUTHOR: Gavin Henry (GH), <ghenry@suretecsystems.com>
774 # COMPANY: Suretec Systems Ltd.
776 # CREATED: 26/06/2006
778 # COPYRIGHT: http://search.cpan.org/dist/perl/pod/perlgpl.pod
779 #===============================================================================
788 chomp( my $pw = ReadLine 0 );
793 print "Enter the password to be encrypted: ";
794 my $pass = get_pass();
796 print "\nConfirm the password: ";
797 my $verify = get_pass();
799 if ( $pass eq $verify ) {
800 my $sha1_enc = Digest::SHA1->new;
801 $sha1_enc->add($pass);
803 print "\nYour encrypted password is: "
804 . $sha1_enc->hexdigest . "\n"
805 . "Paste this into your SQL INSERT/COPY Data.\n";
808 print "\nPasswords do not match!\n";
814 Kennedy Clark, C<hkclark@gmail.com>
816 Please report any errors, issues or suggestions to the author. The
817 most recent version of the Catalyst Tutorial can be found at
818 L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/>.
820 Copyright 2006-2008, Kennedy Clark, under Creative Commons License
821 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).