diff --git a/manual/docs/en.txt b/manual/docs/en.txt index 904a31b05..fc2e9cf1e 100644 --- a/manual/docs/en.txt +++ b/manual/docs/en.txt @@ -1,3 +1,4 @@ ++ Introduction + Getting started + Connection management + Basic schema mapping diff --git a/manual/docs/en/introduction/further-reading.txt b/manual/docs/en/introduction/further-reading.txt new file mode 100644 index 000000000..e0a6d6a94 --- /dev/null +++ b/manual/docs/en/introduction/further-reading.txt @@ -0,0 +1,7 @@ +For people new to object-relational mapping and (object-oriented) domain models we recommend the following literature: + +[http://www.martinfowler.com/books.html Patterns of Enterprise Application Architecture] +Covers a lot of the basic ORM terminology, the different approaches of modeling business logic and the patterns involved. + +[http://domaindrivendesign.org/books/#DDD Domain-Driven Design] +Though serious Domain-Driven Design is currently not possible with Doctrine, this is an excellent resource for good domain modeling, especially in complex business domains, and the terminology around domain models that is pretty widespread nowadays is explained in depth (Entities, Value Objects, Repositories, ...). diff --git a/manual/docs/en/introduction/key-concepts.txt b/manual/docs/en/introduction/key-concepts.txt new file mode 100644 index 000000000..7e727b819 --- /dev/null +++ b/manual/docs/en/introduction/key-concepts.txt @@ -0,0 +1,43 @@ +Now, let's get familar with the key concepts, tools and classes that form the backbone of the Doctrine ORM. + ++++ Doctrine Query Language +The Doctrine Query Language (DQL) is an object query language. It let's you express queries for single objects or full object graphs, using the terminology of your domain model: class names, field names, relations between classes, etc. This is a powerful tool for retrieving or even manipulating objects without breaking the separation of the domain model (field names, class names, ..) from the relational model (table names, column names, ...). +DQL looks very much like SQL and this is intended because it makes it relatively easy to grasp for people knowing SQL. There are, however, a few very important differences you should always keep in mind: + +Take this example: + +from Employee emp join emp.tasks t where emp.salary < 40000 + + +The things to notice about this query: +* We select from **classes** (Employee) +* We join along **associations** (emp.tasks) +* We can reference **fields** (emp.salary) +* There is no join condition (ON x.y = y.x). The associations between your classes and how these are expressed in the database are known to Doctrine (You need to make this mapping known to Doctrine, of course. How to do that is explained later.). + +**DQL expresses a query in the terms of your domain model (your classes, the attributes they have, the relations they have to other classes, etc.)** + +It's very important that we speak about classes, fields and associations between classes here. 'Employee' is **not** a table / table name . It may be that the name of the database table the Employee class is mapped to is indeed named Employee but you should nevertheless adhere to this differentiation of the terminology. This may sound nitpicky since, due to the ActiveRecord approach, your relational model is often very similar to your domain model but it's really important. The column names are rarely the same as the field names and as soon as inheritance is involved the relational model starts to diverge from the domain model. You can have a class Employee that is in fact mapped to several tables in the database. At this point it should be clear that talking about "selecting from the Employee table" is simply wrong then. And as Doctrine development continues there will be more features available that allow the 2 models to diverge even more. + ++++ Metadata Mapping +[todo: explain what this is and how it's done in doctrine. mention the alternative approach (code generation)] + ++++ Classes +The following is a list of the most important classes of the Doctrine ORM and their responsibilities. + +++++ Doctrine::ORM::Entity +The Entity class is the "ActiveRecord" base class. A class needs to extend this base class in order to enable Doctrine to manage it's persistence. +The Entity class provides extending classes with the usual ActiveRecord interface (save()/delete()) and a lot of other methods that are useful in the basic maintenance of the persistent state. + +++++ Doctrine::ORM::Mapper +The Mapper class is the gateway to the main mapping facilities and functionality. If you're going a straight ActiveRecord route you will never have to deal with that class. However, if you don't want to bloat your Entity classes with static finder methods, you can use custom mapper classes that act as your Entity repositories that provide an OO interface for retrieving Entities in the terms of the language of your domain. As you will see, such custom mapper classes come with a lot of functionality out of the box without any custom coding. This is because all custom mapper classes need to inherit from Doctrien::ORM::Mapper [Link to custom mapper docs here?]. + +++++ Doctrine::ORM::EntityManager +The EntityManager class does exactly what the name implies. It manages the lifecycles of all Entities used during the processing of one HTTP request. The EntityManager is the entrypoint for a lot of ORM related functionality. One exception is the usage of the ActiveRecord interface on your Entities, the EntityManager is then involved behind the scenes. One of the key features you'll most likely use the most is the creation of object queries using DQL (Doctrine's OQL implementation). +An EntityManager needs a database connection to operate on (An instance of Doctrine::DBAL::Connection). + +++++ Doctrine::ORM::Query +[coming soon] + +++++ Doctrine::ORM::ClassMetadata +[coming soon] \ No newline at end of file diff --git a/manual/docs/en/introduction/the-big-picture.txt b/manual/docs/en/introduction/the-big-picture.txt new file mode 100644 index 000000000..b7b324165 --- /dev/null +++ b/manual/docs/en/introduction/the-big-picture.txt @@ -0,0 +1,12 @@ ++++ Overview +Doctrine is a tool for object-relational mapping in PHP. It sits on top of PDO and is itself divided into two main layers, The DBAL and the ORM. See the picture below. + +[http://localhost/graphics/doctrine-layers.jpg] + +The DBAL layer completes and extends the basic database abstraction/independance that is already provided by PDO. The DBAL library can be used standalone, if all you want is a powerful database abstraction layer on top of PDO. [Link to DBAL download here]. +The ORM layer depends on the DBAL and therefore, when you load the ORM package the DBAL is already included. + ++++ The terminology used in the manual +**Entity class** : A class whose instances are persisted into a relational database (classes that inherit directly or indirectly from Doctrine::ORM::Entity). +**Entity** : An object that is an instance of an Entity class. +[More key words and short explanations] \ No newline at end of file diff --git a/manual/docs/en/introduction/what-it-is-and-what-not.txt b/manual/docs/en/introduction/what-it-is-and-what-not.txt new file mode 100644 index 000000000..ca172a8cc --- /dev/null +++ b/manual/docs/en/introduction/what-it-is-and-what-not.txt @@ -0,0 +1,23 @@ +The following section tries to explain where Doctrine stands in the world of ORM tools. + +The Doctrine ORM is mainly build around the [http://www.martinfowler.com/eaaCatalog/activeRecord.html ActiveRecord], [http://www.martinfowler.com/eaaCatalog/dataMapper.html Data Mapper] and [http://www.martinfowler.com/eaaCatalog/metadataMapping.html Metadata Mapping] patterns. The former two may sound contradictory but that has it's reasons. Doctrine started out as a plain ActiveRecord implementation. As the featureset grew larger and larger, all the main mapping work of the ORM moved to separate components, among others, the Mappers. Nevertheless, Doctrine has the ActiveRecord-style base class that must be extended by all Entity classes. + +Through extending this specific base class, all the Entity classes get the typical ActiveRecord interface (save/delete/etc.) and it allows Doctrine to easily participate in & monitor the lifecycles of your Entities. The real work, however, is mostly forwarded to other components, like the Mappers. These mappers have the typical Data Mapper interface, save(entity), delete(entity), find(id), etc. So the ActiveRecord base class enables Doctrine to manage your Entities and provides your Entities with the typical ActiveRecord interface whilst the mapping footwork is done elsewhere. As you'll see later, you have a bit of freedom in how you do things, whether you want to use the pure ActiveRecord approach or want to make use of custom Mapper classes. + +However, it's currently not possible to ditch the ActiveRecord approach completely in favor of a Data Mapper approach when using Doctrine, for the reasons described above. + +The ActiveRecord approach comes with it's typical limitations. The most obvious is the enforcement for a class to extend a specific base class in order to be persistent (an Entity). In general, the design of your domain model is pretty much restricted by the design of your relational model. There is an exception though. When dealing with inheritance structures, Doctrine provides some sophisticated mapping strategies which allow your domain model to diverge a bit from the relational model and therefore give you a bit more freedom. Doctrine is in a continous development process and we always try to add new features that provide more freedom in the modeling of the domain. However, as long as Doctrine remains mainly an ActiveRecord approach, there will always be a pretty large, (forced) similarity of these two models. +The current situation is depicted in the following picture. + +[http://localhost/graphics/relational-bounds.jpg] + +As you see in the picture, the domain model can't drift far away from the bounds of the relational model. + +After mentioning these drawbacks, it's time to mention some advantages of the ActiveRecord approach. Apart from the (arguably slightly) simpler programming model, it turns out that the strong similarity of the relational model and the (OO) domain model also has an advantage: It makes it relatively easy to provide powerful generation tools, that can create a basic domain model out of an existing relational schema. And as the domain model can't drift far from the relational model due to the reasons above, such generation and synchronization tools can easily be used throughout the development process. Such tools are one of Doctrine's strengths. + +We think that these limitations of the ActiveRecord approach are not that much of a problem for the majority of web applications because the complexity of the business domains is often moderate, but we also admit that the ActiveRecord approach is certainly not suited for complex business logic (which is often approached using Domain-Driven Design) as it simply puts too many restrictions and has too much influence on your domain model. + +Doctrine is a great tool to drive the persistence of simple or moderately complex domain models(1) and you may even find that it's a good choice for complex domain models if you consider the trade-off between making your domain model more database-centric and implementing all the mapping on your own (because at the time of this writing we are not aware of any powerful ORM tools for PHP that are not based on an ActiveRecord approach). +1) Note that complexity != size. A domain model can be pretty large without being complex and vice versa. Obviously, larger domain models have a greater probability of being complex. + +Now you already know a lot about what Doctrine is and what it is not. If you would like to dive in now and get started right away, jump straight to the next chapter "Getting Started". \ No newline at end of file diff --git a/manual/images/doctrine-layers.jpg b/manual/images/doctrine-layers.jpg new file mode 100644 index 000000000..44c6cf0a0 Binary files /dev/null and b/manual/images/doctrine-layers.jpg differ diff --git a/manual/images/relational-bounds.jpg b/manual/images/relational-bounds.jpg new file mode 100644 index 000000000..73fb4bd3e Binary files /dev/null and b/manual/images/relational-bounds.jpg differ