3 Catalyst::Manual::Tutorial::Appendices - Catalyst Tutorial - Chapter 10: Appendices
8 This is B<Chapter 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 chapter 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 Chapter 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 MyApp::Schema \
325 dbi:mysql:myapp '_username_here_' '_password_here_' '{ AutoCommit => 1 }'
333 Chapter 4: Authentication
339 Create the C<.sql> file for the user/roles data:
341 Open C<myapp02_mysql.sql> in your editor and enter:
344 -- Add users and roles tables, along with a many-to-many join table
347 id INT(11) PRIMARY KEY,
356 id INTEGER PRIMARY KEY,
359 CREATE TABLE user_roles (
362 PRIMARY KEY (user_id, role_id)
365 -- Load up some initial test data
367 INSERT INTO users VALUES (1, 'test01', 'mypass', 't01@na.com', 'Joe', 'Blow', 1);
368 INSERT INTO users VALUES (2, 'test02', 'mypass', 't02@na.com', 'Jane', 'Doe', 1);
369 INSERT INTO users VALUES (3, 'test03', 'mypass', 't03@na.com', 'No', 'Go', 0);
370 INSERT INTO roles VALUES (1, 'user');
371 INSERT INTO roles VALUES (2, 'admin');
372 INSERT INTO user_roles VALUES (1, 1);
373 INSERT INTO user_roles VALUES (1, 2);
374 INSERT INTO user_roles VALUES (2, 1);
375 INSERT INTO user_roles VALUES (3, 1);
379 Load the user/roles data:
381 mysql -ututorial myapp < myapp02_mysql.sql
385 Create the C<.sql> file for the hashed password data:
387 Open C<myapp03_mysql.sql> in your editor and enter:
390 -- Convert passwords to SHA-1 hashes
392 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 1;
393 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 2;
394 UPDATE users SET password = 'e727d1464ae12436e899a726da5b2f11d8381b26' WHERE id = 3;
398 Load the user/roles data:
400 mysql -ututorial myapp < myapp03_mysql.sql
408 Use the following steps to adapt the tutorial to PostgreSQL. Thanks to
409 Louis Moore for the help who was in turn helped by Marcello Romani and
416 Chapter 2: Catalyst Basics
422 Install the required software:
428 The PostgreSQL database server and client.
432 The Perl C<DBD::Pg> module
438 Create the database and a user for the database
440 $ createuser -P catappuser
441 Enter password for new role: <catalyst>
442 Enter it again: <catalyst>
443 Shall the new role be a superuser? (y/n) n
444 Shall the new role be allowed to create databases? (y/n) n
445 Shall the new role be allowed to create more new roles? (y/n) n
447 $ createdb -O catappuser catappdb
452 Create the C<.sql> file and load the data:
458 Open the C<myapp01_psql.sql> in your editor and enter:
462 -- Create a very simple database to hold book and author information
464 -- The sequence is how we get a unique id in PostgreSQL
466 CREATE SEQUENCE books_seq START 5 ;
467 SELECT nextval ('books_seq');
470 id INTEGER PRIMARY KEY DEFAULT nextval('books_seq'),
475 -- 'book_authors' is a many-to-many join table between books & authors
476 CREATE TABLE book_authors (
479 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 catappuser -W catappdb
520 Password for user catappuser: <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 catappdb=> \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 | catappuser
565 public | book_authors | table | catappuser
566 public | books | table | catappuser
569 catappdb=> 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=catappdb' 'catappuser' 'catalyst' '{ AutoCommit => 1 }'
609 Chapter 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 catappuser -W catappdb
668 Password for user catappuser: 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 catappdb=> \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 catappdb=> 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 catappuser -W catappdb
735 Password for user catappuser:
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 catappdb=> \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/Catalyst-Manual/5.70/trunk/lib/Catalyst/Manual/Tutorial/>.
821 Copyright 2006-2008, Kennedy Clark, under Creative Commons License
822 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).