Updates with changes merged/edited from ribasushis review
[dbsrgits/DBIx-Class-Manual-SQLHackers.git] / lib / DBIx / Class / Manual / SQLHackers / CREATE.pod
CommitLineData
6c2a4396 1=head1 NAME
2
3DBIx::Class::Manual::SQLHackers::CREATE - DBIx::Class for SQL Hackers - CREATE
4
5=head1 Table of Contents
6
7=over
8
9=item L<Introduction|DBIx::Class::Manual::SQLHackers::Introduction>
10
11=item CREATE
12
13=item L<INSERT|DBIx::Class::Manual::SQLHackers::INSERT>
14
15=item L<SELECT|DBIx::Class::Manual::SQLHackers::SELECT>
16
17=item L<UPDATE|DBIx::Class::Manual::SQLHackers::UPDATE>
18
19=item L<DELETE|DBIx::Class::Manual::SQLHackers::DELETE>
20
21=item L<BEGIN, COMMIT|DBIx::Class::Manual::SQLHackers::Transactions>
22
cd1e0628 23=back
24
6c2a4396 25=head1 Database structure
26
cd1e0628 27To use DBIx::Class, we need to teach it about the layout of the underlying database. Several methods are supported. The built-in method involves defining your database structure as a set of perl classes, one per resultsource (table, view, etc). The other oft used method is to import the definitions from an existing database using the module
6c2a4396 28L<DBIx::Class::Schema::Loader>.
29
cd1e0628 30Once a DBIx::Class schema (set of classes describing the database) has been created, built-in methods can be used to export it as SQL DDL using L<SQL::Translator>.
6c2a4396 31
32=head2 Using Loader
33
34Install L<DBIx::Class::Schema::Loader> and decide on a name for your schema classes.
35
36Run the included L<dbicdump> script.
37
cd1e0628 38 dbicdump -o dump_directory=./lib \
6c2a4396 39 -o components='["InflateColumn::DateTime"]' \
40 -o preserve_case=1 \
cd1e0628 41 MyApp::Schema dbi:mysql:database=foo user pass '{ quote_names => 1 }'
6c2a4396 42
43
44=head2 Manual Result class creation (and understanding Loader results)
45
cd1e0628 46This section covers the common and oft used CREATE DDL statements that DBIx::Class can replaces with Perl classes: B<CREATE TABLE>, B<CREATE VIEW> and B<CREATE INDEX>. The classes can be used to write the actual SQL DDL to the database or disc, if required.
47
6c2a4396 48=head3 CREATE TABLE
49
50=head4 Standard basic table creation in SQL:
51
52 CREATE TABLE users (
53 id INTEGER AUTO_INCREMENT,
54 username VARCHAR(255),
55 dob DATE,
56 realname VARCHAR(255),
57 password VARCHAR(255)
58 );
59
60We'll get to tables with references (foreign keys) later, here's the translation to DBIx::Class:
61
62The recommended version:
63
64 package MyDatabase::Schema::Result::User;
65 use strict;
66 use warnings;
67
68 use base 'DBIx::Class::Core';
69
70 __PACKAGE__->table('users');
71 __PACKAGE__->add_columns(
72 id => {
73 data_type => 'integer',
74 is_auto_increment => 1,
75 },
76 username => {
77 data_type => 'varchar',
78 size => 255,
79 },
80 dob => {
81 data_type => 'date',
82 },
83 realname => {
84 data_type => 'varchar',
85 size => 255,
86 },
87 password => {
88 data_type => 'varchar',
89 size => 255,
90 },
91 );
92 __PACKAGE__->set_primary_key('id');
93 __PACKAGE__->add_unique_constraint('uniq_username' => ['username']);
94 1;
95
96The fully descriptive version is required if you want to have DBIx::Class create your CREATE TABLE sql for you later. Many DBIC components also use settings in the column info hashrefs to decide how to treat the data for those columns.
97
6c2a4396 98=head4 Table creation with references:
99
100A relational database isn't worth much if we don't actually use references and constraints, so here is an example which constrains the B<user_id> column to only contain B<id> values from the *users* table.
101
102 CREATE TABLE posts (
103 id INTEGER AUTO_INCREMENT,
104 user_id INTEGER,
105 created_date DATETIME,
106 title VARCHAR(255),
107 post TEXT,
108 INDEX posts_idx_user_id (user_id),
109 PRIMARY KEY (id),
110 CONSTRAINT posts_fk_user_id FOREIGN KEY (user_id) REFERENCES users (id)
111 );
112
113In DBIx::Class this is achieved by adding L<relationship|DBIx::Class::Relationship> definitions to the class:
114
115 package MyDatabase::Schema::Result::Post;
116 use strict;
117 use warnings;
118 use base 'DBIx::Class::Core';
119
120 __PACKAGE__->table('posts');
121 __PACKAGE__->add_columns(
122 id => {
123 data_type => 'integer',
124 is_auto_increment => 1,
125 },
126 user_id => {
127 data_type => 'integer',
128 },
129 created_date => {
130 data_type => 'datetime',
131 },
132 title => {
133 data_type => 'varchar',
134 size => 255,
135 },
136 post => {
137 data_type => 'text',
138 },
139 );
140
141 __PACKAGE__->set_primary_key('id');
142 __PACKAGE__->belongs_to('user', 'MyDatabase::Schema::Result::User', 'user_id');
143 1;
144
cd1e0628 145The B<belongs_to> relation creates a B<user> method which returns the user object, as well as storing JOIN information to be used when querying with JOINs. The joined colums on the remote side are taken from the remote PRIMARY KEY value, if not specified, as in this example.
146
147Relationships may also be specified with completely custom JOIN conditions, using any columns, whether the database has them defined as constraints or not, or literal values.
6c2a4396 148
149To allow access from the B<user> object back to the posts they have written, we need to define another relationship in the User class:
150
151 __PACKAGE__->has_many('posts', 'MyDatabase::Schema::Result::Post', 'user_id');
152
153=head3 CREATE VIEW
154
155In SQL, a simple view that returns all users and their posts:
156
157 CREATE VIEW userposts
158 AS
159 SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
160 FROM users
161 JOIN posts ON (users.id = posts.user_id)
162
163In DBIx::Class this can have a Result Class of its own:
164
165 package MyDatabase::Schema::Result::UserPosts;
166
167 use base qw/DBIx::Class::Core/;
168
cd1e0628 169 # Defaults to 'DBIx::Class::ResultSource::Table' unless specified like this
6c2a4396 170 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
171
172 __PACKAGE__->table('user_posts');
cd1e0628 173
174 # Do not emit SQL DDL for this particular resultsource
6c2a4396 175 __PACKAGE__->result_source_instance->is_virtual(1);
cd1e0628 176
6c2a4396 177 __PACKAGE__->result_source_instance->view_definition(
178 "SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
179 FROM users
180 JOIN posts ON (users.id = posts.user_id)"
181 );
182 __PACKAGE__->add_columns(
183 user_id => {
184 data_type => 'integer',
185 },
186 username => {
187 data_type => 'varchar',
188 size => 255,
189 },
190 dob => {
191 data_type => 'date',
192 },
193 realname => {
194 data_type => 'varchar',
195 size => 255,
196 },
197 created_date => {
198 data_type => 'datetime',
199 },
200 title => {
201 data_type => 'varchar',
202 size => 255,
203 },
204 post => {
205 data_type => 'text',
206 },
207
208 );
209 __PACKAGE__->set_primary_key('user_id, post_id');
210
211=head3 CREATE INDEX
212
213=head4 UNIQUE indexes
214
215 CREATE UNIQUE INDEX username_idx ON user (username);
216
217To add extra unique indexes, add the B<add_unique_constraint> call to your Result Class.
218
219 __PACKAGE__->add_unique_constraint('username_idx' => ['username']);
220
cd1e0628 221=head3 Outputting SQL DDL
6c2a4396 222
cd1e0628 223Once the DBIC schema has been defined, you can outout the SQL DDL needed to create the schema in your database (using the RDBMS-specific flavor of SQL DDL) in one of several ways.
6c2a4396 224
225=head4 Deploy directly to the database
226
227Create a schema object with the correct database connection, then call B<deploy> on it.
228
229 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
230 $schema->deploy({add_drop_table => 1});
231
232L<DBIx::Class::Schema/deploy> has the documentation for the deploy method.
233
234=head4 Write out SQL files
235
cd1e0628 236Create a schema object with the a database connection (any will do), and call the B<create_ddl_dir> method on it.
6c2a4396 237
238 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
239 $schema->create_ddl_dir(['SQLite', 'MySQL']);
240
cd1e0628 241If called with no arguments, this method will create an SQL file each for MySQL, PostgreSQL and SQLite. More databases are supported by L<SQL::Translator> if necessary.
6c2a4396 242
243=head4 SQL files for upgrades (ALTER TABLE)
244
cd1e0628 245DBIC can also make use of L<SQL::Translator::Diff> to write out ALTER TABLE statements when the schema classes are changed.
6c2a4396 246
247To do this, make sure that you set a B<$VERSION> in your main Schema class, and run B<create_ddl_dir> on the initial version to provide a baseline.
248
249After the schema has changed, change the B<$VERSION> value and re-run B<create_ddl_dir>.
250
251 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
252 $schema->create_ddl_dir(\@databases, undef, '.', '0.1');