Multi-Component.txt 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. = Multi-Component Data Model =
  2. Propel comes along with packaging capabilities that allow you to more easily integrate Propel into a packaged or modularized application.
  3. == Muliple Schemas ==
  4. You can use as many `schema.xml` files as you want. Schema files have to be named `(*.)schema.xml`, so names like `schema.xml`, `package1.schema.xml`, `core.package1.schema.xml` are all acceptable. These files ''have'' to be located in your project directory.
  5. Each schema file has to contain a `<database>` element with a `name` attribute. This name references the connection settings to be used for this database (and configured in the `runtime-conf.xml`), so separated schemas can share a common database name.
  6. Whenever you call a propel build taks, Propel will consider all these schema files and build the classes (or the SQL) for all the tables.
  7. == Understanding Packages ==
  8. In Propel, a ''package'' represents a group of models. This is a convenient way to organize your code in a modularized way, since classes and SQL files of a given package are be grouped together and separated from the other packages. By carefully choosing the package of each model, applications end up in smaller, independent modules that are easier to manage.
  9. === Package Cascade ===
  10. The package is defined in a configuration cascade. You can set it up for the whole project, for all the tables of a schema, or for a single table.
  11. For the whole project, the main package is set in the `build.properties`:
  12. {{{
  13. #!ini
  14. propel.targetPackage = my_project
  15. }}}
  16. By default, all the tables of all the schemas in the project use this package. However, you can override the package for a given `<database>` by setting its `package` attribute:
  17. {{{
  18. #!xml
  19. <!-- in author.schema.xml -->
  20. <database package="author" name="bookstore">
  21. <table name="author">
  22. <!-- author columns -->
  23. </table>
  24. </database>
  25. <!-- in book.schema.xml -->
  26. <database package="book" name="bookstore">
  27. <table name="book">
  28. <!-- book columns -->
  29. </table>
  30. <table name="review">
  31. <!-- review columns -->
  32. </table>
  33. </database>
  34. }}}
  35. In this example, thanks to the `package` attribute, the tables are grouped into the following packages:
  36. * `my_project.author` package: `author` table
  37. * `my_project.book` package: `book` and `review` tables
  38. '''Warning''': If you separate tables related by a foreign key into separate packages (like `book` and `author` in this example), you must enable the `packageObjectModel` build property to let Propel consider other packages for relations.
  39. You can also override the `package` attribute at the `<table>` element level.
  40. {{{
  41. #!xml
  42. <!-- in author.schema.xml -->
  43. <database package="author" name="bookstore">
  44. <table name="author">
  45. <!-- author columns -->
  46. </table>
  47. </database>
  48. <!-- in book.schema.xml -->
  49. <database package="book" name="bookstore">
  50. <table name="book">
  51. <!-- book columns -->
  52. </table>
  53. <table name="review" package="review">
  54. <!-- review columns -->
  55. </table>
  56. </database>
  57. }}}
  58. This ends up in the following package:
  59. * `my_project.author` package: `author` table
  60. * `my_project.book` package: `book` table
  61. * `my_project.review` package: `review` table
  62. Notice that tables can end up in separated packages even though they belong to the same schema file.
  63. '''Tip''': You can use dots in a package name to add more package levels.
  64. === Packages and Generated Model Files ===
  65. The `package` attribute of a table translates to the directory in which Propel generates the Model classes for this table.
  66. For instance, if no `package` attribute is defined at the database of table level, Propel places all classes according to the `propel.targetPackage` from the `build.properties`:
  67. {{{
  68. build/
  69. classes/
  70. my_project/
  71. om/
  72. map/
  73. Author.php
  74. AuthorPeer.php
  75. AuthorQuery.php
  76. Book.php
  77. BookPeer.php
  78. BookQuery.php
  79. Review.php
  80. ReviewPeer.php
  81. ReviewQuery.php
  82. }}}
  83. You can further tweak the location where Propel puts the created files by changing the `propel.output.dir` build property. By default this property is set to:
  84. {{{
  85. #!ini
  86. propel.output.dir = ${propel.project.dir}/build
  87. }}}
  88. You can change it to use any other directory as your build directory.
  89. If you set up packages for `<database>` elements, Propel splits up the generated model classes into subdirectories named after the package attribute:
  90. {{{
  91. build/
  92. classes/
  93. my_project/
  94. author/
  95. om/
  96. map/
  97. Author.php
  98. AuthorPeer.php
  99. AuthorQuery.php
  100. book/
  101. om/
  102. map/
  103. Book.php
  104. BookPeer.php
  105. BookQuery.php
  106. Review.php
  107. ReviewPeer.php
  108. ReviewQuery.php
  109. }}}
  110. And of course, if you specialize the `package` attribute per table, you can have one table use its own package:
  111. {{{
  112. build/
  113. classes/
  114. my_project/
  115. author/
  116. om/
  117. map/
  118. Author.php
  119. AuthorPeer.php
  120. AuthorQuery.php
  121. book/
  122. om/
  123. map/
  124. Book.php
  125. BookPeer.php
  126. BookQuery.php
  127. review/
  128. om/
  129. map/
  130. Review.php
  131. ReviewPeer.php
  132. ReviewQuery.php
  133. }}}
  134. === Packages And SQL Files ===
  135. Propel also considers packages for SQL generation. In practice, Propel generates one SQL file per package. Each file contains the CREATE TABLE SQL statements necessary to create all the tables of a given package.
  136. So by default, all the tables end up in a single SQL file:
  137. {{{
  138. build/
  139. sql/
  140. schema.sql
  141. }}}
  142. If you specialize the `package` for each `<database>` element, Propel uses it for SQL files:
  143. {{{
  144. build/
  145. sql/
  146. author.schema.sql // contains CREATE TABLE author
  147. book.schema.sql // contains CREATE TABLE book and CREATE TABLE review
  148. }}}
  149. And, as you probably expect it, a package overridden at the table level also accounts for an independent SQL file:
  150. {{{
  151. build/
  152. sql/
  153. author.schema.sql // contains CREATE TABLE author
  154. book.schema.sql // contains CREATE TABLE book
  155. review.schema.sql // contains CREATE TABLE review
  156. }}}
  157. == Understanding The packageObjectModel Build Property ==
  158. The `propel.packageObjectModel` build property enables the "packaged" build process. This modifies the build tasks behavior by joining `<database>` elements of the same name - but keeping their packages separate. That allows to split a large schema into several files, regardless of foreign key dependencies, since Propel will join all schemas using the same database name.
  159. To switch this on, simply add the following line to the `build.properties` file in your project directory:
  160. {{{
  161. propel.packageObjectModel = true
  162. }}}
  163. == The Bookstore Packaged Example ==
  164. In the bookstore-packaged example you'll find the following schema files:
  165. * author.schema.xml
  166. * book.schema.xml
  167. * club.schema.xml
  168. * media.schema.xml
  169. * publisher.schema.xml
  170. * review.schema.xml
  171. * log.schema.xml
  172. Each schema file has to contain a `<database>` tag that has its `package` attribute set to the package name where ''all'' of the tables in this schema file/database belong to.
  173. For example, in the bookstore-packaged example the `author.schema.xml` contains the following `<database>` tag:
  174. {{{
  175. <database package="core.author" name="bookstore" [...]>
  176. }}}
  177. That means, that the Author OM classes will be created in a subdirectory `core/author/` of the build output directory.
  178. You can have more than one schema file that belong to one package. For example, in the the bookstore-packaged example both the `book.schema.xml` and `media.schema.xml` belong to the same package "core.book". The generated OM classes for these schemas will therefore end up in the same `core/book/` subdirectory.
  179. === The OM build ===
  180. To run the packaged bookstore example build simply go to the `propel/test/fixtures/bookstore-packages/` directory and type:
  181. {{{
  182. ../../../generator/bin/propel-gen om
  183. }}}
  184. This should run without any complaints. When you have a look at the projects/bookstore-packaged/build/classes directory, the following directory tree should have been created:
  185. {{{
  186. addon/
  187. club/
  188. BookClubList.php
  189. BookClubListPeer.php
  190. BookListRel.php
  191. BookListRelPeer.php
  192. core/
  193. author/
  194. Author.php
  195. AuthorPeer.php
  196. book/
  197. Book.php
  198. BookPeer.php
  199. Media.php
  200. MediaPeer.php
  201. publisher/
  202. Publisher.php
  203. PublisherPeer.php
  204. review/
  205. Review.php
  206. ReviewPeer.php
  207. util/
  208. log/
  209. BookstoreLog.php
  210. BookstoreLogPeer.php
  211. }}}
  212. (The additional subdirectories map/ and om/ in each of these directories have been omitted for clarity.)
  213. == The SQL build ==
  214. From the same schema files, run the SQL generation by calling:
  215. {{{
  216. ../../../generator/bin/propel-gen sql
  217. }}}
  218. Then, have a look at the `build/sql/` directory: you will see that for each package (that is specified as a package attribute in the schema file database tags), one sql file has been created:
  219. * addon.club.schema.sql
  220. * core.author.schema.sql
  221. * core.book.schema.sql
  222. * core.publisher.schema.sql
  223. * core.review.schema.sql
  224. * util.log.schema.sql
  225. These files contain the CREATE TABLE SQL statements necessary for each package.
  226. When you now run the insert-sql task by typing:
  227. {{{
  228. ../../../generator/bin/propel-gen insert-sql
  229. }}}
  230. these SQL statements will be executed on a SQLite database located in the Propel/generator/test/ directory.