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)
482 CREATE SEQUENCE authors_seq START 8 ;
483 SELECT nextval ('authors_seq');
485 CREATE TABLE authors (
486 id INTEGER PRIMARY KEY DEFAULT nextval('authors_seq'),
491 --- Load some sample data
493 INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5);
494 INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5);
495 INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4);
496 INSERT INTO books VALUES (4, 'Perl Cookbook', 5);
497 INSERT INTO books VALUES (5, 'Designing with Web Standards', 5);
498 INSERT INTO authors VALUES (1, 'Greg', 'Bastien');
499 INSERT INTO authors VALUES (2, 'Sara', 'Nasseh');
500 INSERT INTO authors VALUES (3, 'Christian', 'Degu');
501 INSERT INTO authors VALUES (4, 'Richard', 'Stevens');
502 INSERT INTO authors VALUES (5, 'Douglas', 'Comer');
503 INSERT INTO authors VALUES (6, 'Tom', 'Christiansen');
504 INSERT INTO authors VALUES (7, 'Nathan', 'Torkington');
505 INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman');
506 INSERT INTO book_authors VALUES (1, 1);
507 INSERT INTO book_authors VALUES (1, 2);
508 INSERT INTO book_authors VALUES (1, 3);
509 INSERT INTO book_authors VALUES (2, 4);
510 INSERT INTO book_authors VALUES (3, 5);
511 INSERT INTO book_authors VALUES (4, 6);
512 INSERT INTO book_authors VALUES (4, 7);
513 INSERT INTO book_authors VALUES (5, 8);
519 $ psql -U catmyapp -W mycatapp
520 Password for user catmyapp: catalyst
521 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
523 Type: \copyright for distribution terms
524 \h for help with SQL commands
525 \? for help with psql commands
526 \g or terminate with semicolon to execute query
529 mycatapp=> \i myapp01_psql.sql
537 psql:myapp01_psql.sql:11: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "books_pkey" for table "books"
539 psql:myapp01_psql.sql:19: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "book_authors_pkey" for table
548 psql:myapp01_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "authors_pkey" for table "authors"
558 Make sure the data loaded correctly:
562 Schema | Name | Type | Owner
563 --------+--------------+-------+----------
564 public | authors | table | catmyapp
565 public | book_authors | table | catmyapp
566 public | books | table | catmyapp
569 mycatapp=> select * from books;
571 ----+------------------------------------+--------
572 1 | CCSP SNRS Exam Certification Guide | 5
573 2 | TCP/IP Illustrated, Volume 1 | 5
574 3 | Internetworking with TCP/IP Vol.1 | 4
575 4 | Perl Cookbook | 5
576 5 | Designing with Web Standards | 5
585 After the steps where you:
589 create lib/MyAppDB.pm
591 create lib/MyAppDB/Book.pm
593 create lib/MyAppDB/Author.pm
595 create lib/MyAppDB/BookAuthor.pm
600 Generate the model using the Catalyst "_create.pl" script:
602 script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB 'dbi:Pg:dbname=mycatapp' 'catmyapp' 'catalyst' '{ AutoCommit => 1 }'
609 Part 4: Authentication
615 Create the C<.sql> file for the user/roles data:
617 Open C<myapp02_psql.sql> in your editor and enter:
620 -- Add users and roles tables, along with a many-to-many join table
623 CREATE SEQUENCE users_seq START 3 ;
624 SELECT nextval ('users_seq');
627 id INTEGER PRIMARY KEY DEFAULT nextval('users_seq'),
636 CREATE SEQUENCE roles_seq START 2 ;
637 SELECT nextval ('roles_seq');
640 id INTEGER PRIMARY KEY DEFAULT nextval('roles_seq'),
644 CREATE TABLE user_roles (
647 PRIMARY KEY (user_id, role_id)
651 -- Load up some initial test data
653 INSERT INTO users VALUES (1, 'test01', 'mypass', 't01@na.com', 'Joe', 'Blow', 1);
654 INSERT INTO users VALUES (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe', 1);
655 INSERT INTO users VALUES (3, 'test03', 'mypass', 't03@na.com', 'No', 'Go', 0);
656 INSERT INTO roles VALUES (1, 'user');
657 INSERT INTO roles VALUES (2, 'admin');
658 INSERT INTO user_roles VALUES (1, 1);
659 INSERT INTO user_roles VALUES (1, 2);
660 INSERT INTO user_roles VALUES (2, 1);
661 INSERT INTO user_roles VALUES (3, 1);
667 $ psql -U catmyapp -W mycatapp
668 Password for user catmyapp: catalyst
669 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
671 Type: \copyright for distribution terms
672 \h for help with SQL commands
673 \? for help with psql commands
674 \g or terminate with semicolon to execute query
677 mycatapp=> \i myapp02_psql.sql
685 psql:myapp02_psql.sql:16: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users"
693 psql:myapp02_psql.sql:24: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "roles_pkey" for table "roles"
695 psql:myapp02_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "user_roles_pkey" for table "user_roles"
708 mycatapp=> select * from users;
709 id | username | password | email_address | first_name | last_name | active
710 ----+----------+----------+---------------+------------+-----------+--------
711 1 | test01 | mypass | t01@na.com | Joe | Blow | 1
712 2 | test02 | mypass | t02@na.com | Jane | Doe | 1
713 3 | test03 | mypass | t03@na.com | No | Go | 0
719 Create the C<.sql> file for the hashed password data:
721 Open C<myapp03_psql.sql> in your editor and enter:
724 -- Convert passwords to SHA-1 hashes
726 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 1;
727 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 2;
728 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 3;
734 $ psql -U catmyapp -W mycatapp
735 Password for user catmyapp:
736 Welcome to psql 8.1.8, the PostgreSQL interactive terminal.
738 Type: \copyright for distribution terms
739 \h for help with SQL commands
740 \? for help with psql commands
741 \g or terminate with semicolon to execute query
744 mycatapp=> \i myapp03_psql.sql
756 =head1 APPENDIX 3: IMPROVED HASHING SCRIPT
758 Here is an improved SHA-1 hashing script from Gavin Henry that does
759 not expose the passwords to "capture" on the command line.
762 #===============================================================================
766 # USAGE: ./enc_pass.pl
768 # DESCRIPTION: Encrypt a Password using SHA-1
774 # AUTHOR: Gavin Henry (GH), <ghenry@suretecsystems.com>
775 # COMPANY: Suretec Systems Ltd.
777 # CREATED: 26/06/2006
779 # COPYRIGHT: http://search.cpan.org/dist/perl/pod/perlgpl.pod
780 #===============================================================================
789 chomp( my $pw = ReadLine 0 );
794 print "Enter the password to be encrypted: ";
795 my $pass = get_pass();
797 print "\nConfirm the password: ";
798 my $verify = get_pass();
800 if ( $pass eq $verify ) {
801 my $sha1_enc = Digest::SHA1->new;
802 $sha1_enc->add($pass);
804 print "\nYour encrypted password is: "
805 . $sha1_enc->hexdigest . "\n"
806 . "Paste this into your SQL INSERT/COPY Data.\n";
809 print "\nPasswords do not match!\n";
815 Kennedy Clark, C<hkclark@gmail.com>
817 Please report any errors, issues or suggestions to the author. The
818 most recent version of the Catalyst Tutorial can be found at
819 L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/>.
821 Copyright 2006-2008, Kennedy Clark, under Creative Commons License
822 (L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).