Cleanup and remove non-working parts and comments
[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
0e8be732 27To use DBIx::Class, we need to teach it about the layout of the
28underlying database. Several methods of doing this are available. If
29you have an existing database the most straightforward way is to use
30the module L<DBIx::Class::Schema::Loader>, which will introspect your
31database and generate individual classes representing every table and
32view in your database. For new projects one usually writes these
33classes by hand as described below. If you find the methods provided
34by L<DBIx::Class> core overly verbose, you can try to define your
35result classes via the more concise syntax of L<DBIx::Class::Candy>
36(the result is fully compatible with L<DBIx::Class>).
37
38Once a DBIx::Class schema (set of classes describing the database) has
39been created, built-in methods can be used to export it as SQL DDL
40using L<SQL::Translator>.
6c2a4396 41
42=head2 Using Loader
43
44Install L<DBIx::Class::Schema::Loader> and decide on a name for your schema classes.
45
46Run the included L<dbicdump> script.
47
cd1e0628 48 dbicdump -o dump_directory=./lib \
6c2a4396 49 -o components='["InflateColumn::DateTime"]' \
50 -o preserve_case=1 \
cd1e0628 51 MyApp::Schema dbi:mysql:database=foo user pass '{ quote_names => 1 }'
6c2a4396 52
53
54=head2 Manual Result class creation (and understanding Loader results)
55
cd1e0628 56This 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.
57
6c2a4396 58=head3 CREATE TABLE
59
60=head4 Standard basic table creation in SQL:
61
62 CREATE TABLE users (
63 id INTEGER AUTO_INCREMENT,
64 username VARCHAR(255),
65 dob DATE,
66 realname VARCHAR(255),
67 password VARCHAR(255)
68 );
69
70We'll get to tables with references (foreign keys) later, here's the translation to DBIx::Class:
71
72The recommended version:
73
74 package MyDatabase::Schema::Result::User;
75 use strict;
76 use warnings;
77
78 use base 'DBIx::Class::Core';
79
80 __PACKAGE__->table('users');
81 __PACKAGE__->add_columns(
82 id => {
83 data_type => 'integer',
84 is_auto_increment => 1,
85 },
86 username => {
87 data_type => 'varchar',
88 size => 255,
89 },
90 dob => {
91 data_type => 'date',
92 },
93 realname => {
94 data_type => 'varchar',
95 size => 255,
96 },
97 password => {
98 data_type => 'varchar',
99 size => 255,
100 },
101 );
102 __PACKAGE__->set_primary_key('id');
103 __PACKAGE__->add_unique_constraint('uniq_username' => ['username']);
104 1;
105
106The 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.
107
2f41b1a9 108# perhaps "... with declared relations / Declaring relationships" ? "references" doesn't sound right in the context imho
0e8be732 109# in SQL land a relation == a table, since I'm talking to SQL heads I don't want to get that wrong.
6c2a4396 110=head4 Table creation with references:
111
112A 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.
113
114 CREATE TABLE posts (
115 id INTEGER AUTO_INCREMENT,
116 user_id INTEGER,
117 created_date DATETIME,
118 title VARCHAR(255),
119 post TEXT,
120 INDEX posts_idx_user_id (user_id),
121 PRIMARY KEY (id),
122 CONSTRAINT posts_fk_user_id FOREIGN KEY (user_id) REFERENCES users (id)
123 );
124
125In DBIx::Class this is achieved by adding L<relationship|DBIx::Class::Relationship> definitions to the class:
126
127 package MyDatabase::Schema::Result::Post;
128 use strict;
129 use warnings;
130 use base 'DBIx::Class::Core';
131
132 __PACKAGE__->table('posts');
133 __PACKAGE__->add_columns(
134 id => {
135 data_type => 'integer',
136 is_auto_increment => 1,
137 },
138 user_id => {
139 data_type => 'integer',
140 },
141 created_date => {
142 data_type => 'datetime',
143 },
144 title => {
145 data_type => 'varchar',
146 size => 255,
147 },
148 post => {
149 data_type => 'text',
150 },
151 );
152
153 __PACKAGE__->set_primary_key('id');
154 __PACKAGE__->belongs_to('user', 'MyDatabase::Schema::Result::User', 'user_id');
155 1;
156
2f41b1a9 157The 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. When not explicitly specified (as in this example), the columns for the JOIN clause default to the remote PRIMARY KEY column set.
cd1e0628 158
159Relationships 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 160
2f41b1a9 161Each relationship declaration in DBIC is one-way only.
6c2a4396 162To allow access from the B<user> object back to the posts they have written, we need to define another relationship in the User class:
163
164 __PACKAGE__->has_many('posts', 'MyDatabase::Schema::Result::Post', 'user_id');
165
166=head3 CREATE VIEW
167
168In SQL, a simple view that returns all users and their posts:
169
170 CREATE VIEW userposts
171 AS
172 SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
173 FROM users
174 JOIN posts ON (users.id = posts.user_id)
175
176In DBIx::Class this can have a Result Class of its own:
177
178 package MyDatabase::Schema::Result::UserPosts;
179
180 use base qw/DBIx::Class::Core/;
181
cd1e0628 182 # Defaults to 'DBIx::Class::ResultSource::Table' unless specified like this
6c2a4396 183 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
184
185 __PACKAGE__->table('user_posts');
cd1e0628 186
187 # Do not emit SQL DDL for this particular resultsource
6c2a4396 188 __PACKAGE__->result_source_instance->is_virtual(1);
cd1e0628 189
6c2a4396 190 __PACKAGE__->result_source_instance->view_definition(
191 "SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
192 FROM users
193 JOIN posts ON (users.id = posts.user_id)"
194 );
195 __PACKAGE__->add_columns(
196 user_id => {
197 data_type => 'integer',
198 },
199 username => {
200 data_type => 'varchar',
201 size => 255,
202 },
203 dob => {
204 data_type => 'date',
205 },
206 realname => {
207 data_type => 'varchar',
208 size => 255,
209 },
210 created_date => {
211 data_type => 'datetime',
212 },
213 title => {
214 data_type => 'varchar',
215 size => 255,
216 },
217 post => {
218 data_type => 'text',
219 },
220
221 );
222 __PACKAGE__->set_primary_key('user_id, post_id');
223
224=head3 CREATE INDEX
225
226=head4 UNIQUE indexes
227
228 CREATE UNIQUE INDEX username_idx ON user (username);
229
230To add extra unique indexes, add the B<add_unique_constraint> call to your Result Class.
231
232 __PACKAGE__->add_unique_constraint('username_idx' => ['username']);
233
7d48ee14 234=head4 NON-UNIQUE indexes
235
236 CREATE INDEX user_email_idx ON user (username, email);
237
238These are not created or used by DBIx::Class itself, but can be added so that deploying (creating DDL SQL from your Schema) can include them.
239
240The B<sqlt_deply_hook> method allows you to add L<SQL::Translator> code to your Result class. It is called with the SQL::Translator::Schema::Table object, and allows you to amend the Table before it is converted into SQL.
241
242 sub sqlt_deploy_hook {
243 my ($self, $sqlt_table) = @_;
244
245 $sqlt_table->add_index(name => 'user_email_idx', fields => ['username', 'email']);
246 }
247
0e8be732 248
cd1e0628 249=head3 Outputting SQL DDL
6c2a4396 250
cd1e0628 251Once 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 252
253=head4 Deploy directly to the database
254
255Create a schema object with the correct database connection, then call B<deploy> on it.
256
257 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
258 $schema->deploy({add_drop_table => 1});
259
260L<DBIx::Class::Schema/deploy> has the documentation for the deploy method.
261
262=head4 Write out SQL files
263
cd1e0628 264Create a schema object with the a database connection (any will do), and call the B<create_ddl_dir> method on it.
6c2a4396 265
266 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
267 $schema->create_ddl_dir(['SQLite', 'MySQL']);
268
cd1e0628 269If 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 270
271=head4 SQL files for upgrades (ALTER TABLE)
272
cd1e0628 273DBIC can also make use of L<SQL::Translator::Diff> to write out ALTER TABLE statements when the schema classes are changed.
6c2a4396 274
275To 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.
276
277After the schema has changed, change the B<$VERSION> value and re-run B<create_ddl_dir>.
278
279 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
280 $schema->create_ddl_dir(\@databases, undef, '.', '0.1');