Start on the first draft of the spec
[dbsrgits/dbic-future.git] / lib / DBIx / Class / Manual / Specification.pm
CommitLineData
7848cf7a 1=head1 NAME
2
3DBIx::Class::Manual::Specification
4
5=head1 SYNOPSIS
6
7This discusses the specification for DBIx::Class v0.09. Along with discussing
8new features, it will also include proper specification for features that exist
9in the DBIx::Class 0.08 versions that will be supported in DBIx::Class 0.09.
10Where appropriate, it will also discuss specifications for Data::Query and any
11other modules/distributions.
12
13=head1 MOTIVATIONS
14
15DBIx::Class has become one of, if not the, premier ORMs in the Perl community.
16However, its featureset has grown organically. As such, some features that were
17considered a good idea at one time proved to be implemented in such a way that
18prevented proper implementation of other features down the road. Examples
19include prefetching and searching.
20
21This document means to provide a solid foundation for future development so as
22to prevent painting the distribution into a corner for features that have not
23been conceived of at this time.
24
25=head1 GOALS
26
27This specification will be driven by the following design goals.
28
29=head2 Database-agnostic usage
30
31One of the biggest selling points of an ORM is that a programmer should be able
32to change the relational database used to back a given application without
33having to change anything but configuration. And, to a point, this works
34relatively well. Until it doesn't. DBIx::Class 0.09 will change that.
35
36=head2 Database-specific optimization
37
38As it turns out, the drive to be database-agnostic, makes it very hard to
39optimize for a given specific database's strengths. In order to support as many
40databases, the SQL generated generally ends up being at the lowest common
41denominator. This gives ORMs a bad name where performance is concerned. But, it
42doesn't have to be that way and DBIx::Class 0.09 will demonstrate how.
43
44=head2 Datastore-agnostic usage
45
46Data doesn't just live in relational databases anymore. There are many reasons,
47for this, the primary one being that the relational model doesn't necessarily
48reflect the structure of certain data models. But, there are many times when
49relational calculus represents the proper way of manipulating that data. Or,
50more commonly, a given relational query needs to merge data from relational and
51non-relational sources. DBIx::Class, along with Data::Query, will provide a
52single API for manipulating data in a relational fashion, regardless of whether
53that manipulation is in a datastore, within Perl, or both.
54
55=head2 Intuitive API
56
57Every API has unavoidable gribbly bits. This falls out of the fact that the
58problemspace a given API solves can never be fully mapped to it (an extension
59of Godel's Incompleteness Theorem). However, like Perl itself, the API should be
60organized and optimized so that the user only needs to know a minimum of the
61API's functionality in order to accomplish the most common tasks. Furthermore,
62that minimum should be easily discoverable in simple synopses and examples.
63
64=head2 Extensible API and backend
65
66Without breaking or, in as many cases as possible I<knowing>, existing backend
67implementation details, the functionality of DBIx::Class should be extensible.
68Both the API (new contact points) and backend (new datastores, etc) should be
69extended knowing a simple API for doing so. This implies that as many pieces as
70possible of the backend functionality should be overridable separate from every
71other piece.
72
73=head1 RESTRICTIONS
74
75Fill this part in.
76
77=head1 RELATIONAL THEORY
78
79(B<Author's note:> To understand the fundamental underpinnings of DBIx::Class
800.09's choice of features, it is necessary to have a common understanding of
81relational theory. I recommend that everyone at least read this section once in
82order to be familiar with the terms I use throughout this document.)
83
84Relational theory (calculus or algebra - the difference is esoteric) is, at its
85roots, all about set theory and set manipulations. Each row in a table (or
86tuple) is an element of a set. The various clause (or operations) in a SQL
87statement can be viewed as set manipulators that take one or more sets of tuples
88as input and provide a set of tuples as output.
89
90A SQL statement has many clauses and they are evaluated in a very specific order
91that is different from the order they are presented. (As mutations share all of
92their clauses with queries and evaluate in the same order, only queries will be
93discussed here.) The order of evaluation for a SELECT statement is:
94
95=over 4
96
97=item * FROM (with JOINs evaluated in left-to-right order)
98
99=item * WHERE (with AND/OR evaluated in left-to-right order within each
100parenthetical block)
101
102=item * GROUP BY
103
104=item * SELECT
105
106=item * HAVING
107
108=item * ORDER BY
109
110=back
111
112(Expand here.)
113
114=head1 FEATURES
115
116=head2 Basic Features
117
118An ORM must provide some very basic features. They are, in essence, the ability
119to:
120
121=over 4
122
123=item * Retrieve data from a relational database (a.k.a., select)
124
125=item * Insert, update, and delete in that relational database (a.k.a., mutate)
126
127=back
128
129These functions are generally achieved by providing some API to the SELECT
130statement that returns a collection of objects. These objects then allow for
131updating and deleting. The same API that allows for SELECT also, generally, will
132allow for creation and, possibly, deletion. Most ORMs do this modelling by
133mapping a class to a table and an instance of that class to a given row in that
134table.
135
136DBIx::Class takes a different approach. Given rows in a table are represented by
137objects, but the table as a whole is also represented by an object. There is no
138class that represents the table in itself. Instead, there is a class that is
139used to instantiate the rows of a table and another class that is used to
140instantiate objects that represent SQL clauses for statements against that
141table. The former is the Row class and the latter is the ResultSet class. This
142separation allows for greater expressivity when dealing with a given table.
143
144DBIx::Class 0.09 extends these concepts by adding a third layer - the source.
145
146(Expand here.)
147
148=head3 Sources
149
150A source, at its simplest, is the representation of a single table in a
151relational database. For example, the table `artists`. But, a source can be
152much more than that. Within a relational database, "`artists JOIN cds`" forms a
153source containing the columns of both `artists` and `cds`. Taken to the logical
154extreme, the FROM clause of a query forms a single source. A subquery can also
155be viewed as a source. (In fact, any table or join can be viewed as the subquery
156"(SELECT * FROM table) AS table".)
157
158=head3 Resultsets
159
160The resultset is arguably the single most important breakthrough in DBIx::Class.
161It allows for the gradual building of a SQL statement and reuse of that building
162for more than just SELECT statements. In addition to being able to separate
163responsibilites by letting different pieces of an application (such as security)
164decorate the resultset appropriately, a resultset can also be reused for various
165needs. The same resultset can be used for a query, a mass update, a mass delete,
166or anything else.
167
168Under the hood, a resultset has a representation for each SQL clause. Each usage
169of the resultset will take the clauses that make sense for that usage and leave
170the others.
171
172(Expand here, detailing each usage of a resultset and the clauses that each
173uses.)
174
175=head3 Rows
176
177Traditionally, the row object is a hashref representing a row in a table. This
178representation is simple to implement, meets the 80/20 case, and completely
179wrong. It fails when dealing with GROUP BY clauses and custom queries. The
180proper treatment of a row object is that it represents the SELECT clause of the
181resultset that generated it. In the 80/20 case, the SELECT clause will be all
182the columns of the primary table being selected. By moving the defintion of the
183row object into the resultset, the row object's definition is closer to its
184usage.
185
186Under the hood, the row object is defined by using anonymous classes built with
187roles, one role for each column. The roles for the columns are defined in the
188definitions for each table. Those roles flow from the source(s), through the
189resultset and into the row objects.
190
191=head2 Queries as streams
192
193A grouping of data can be viewed as either a collection or a stream. The main
194difference is that a collection is eager and a stream is lazy. For large
195datasets, collections can be very expensive in terms of memory and time (filling
196that memory). Streams, on the other hand, defer loading anything into memory
197until the last possible moment, but are easily convertible into a collection as
198needed. (q.v. Higher Order Perl for more information.)
199
200=head2
201
202=head1 TODO
203
204=over 4
205
206=item * L</RESTRICTIONS> section needs to be filled in.
207
208=back
209
210=head1 AUTHOR(S)
211
212robkinyon: Rob Kinyon C<< <rkinyon@cpan.org> >>
213
214=head1 LICENSE
215
216You may distribute this code under the same terms as Perl itself.
217
218=cut