root/trunk/Sources/BaseTen.h @ 805

Revision 735, 30.0 kB (checked in by tsnorri, 2 years ago)

Added a remark about required Xcode version

  • Property svn:keywords set to Id
Line 
1//
2// BaseTen.h
3// BaseTen
4//
5// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
6//
7// Before using this software, please review the available licensing options
8// by visiting http://basetenframework.org/licensing/ or by contacting
9// us at sales@karppinen.fi. Without an additional license, this software
10// may be distributed only in compliance with the GNU General Public License.
11//
12//
13// This program is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License, version 2.0,
15// as published by the Free Software Foundation.
16//
17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with this program; if not, write to the Free Software
24// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25//
26// $Id$
27//
28
29//FIXME: this doesn't seem to work.
30#if 0 && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
31#define NSUInteger unsigned int
32#define NSInteger int
33#endif
34
35
36#import <BaseTen/BXConstants.h>
37#import <BaseTen/BXDatabaseContext.h>
38#import <BaseTen/BXDatabaseContextDelegateProtocol.h>
39#import <BaseTen/BXDatabaseObject.h>
40#import <BaseTen/BXDatabaseObjectID.h>
41#import <BaseTen/BXEntityDescription.h>
42#import <BaseTen/BXAttributeDescription.h>
43#import <BaseTen/BXRelationshipDescription.h>
44#import <BaseTen/BXException.h>
45
46/*
47 * Helpful breakpoints:
48 *
49 * _log4AssertionDebug
50 * bx_error_during_rollback
51 * bx_error_during_clear_notification
52 * bx_test_failed
53 * pgts_hom_unrecognized_selector
54 * BXHandleError2
55 *
56 */
57
58/**
59 * \defgroup baseten BaseTen
60 * BaseTen is linked to Foundation, Security and IOKit frameworks and
61 * libcrypto, libssl and libstdc++ dynamic libraries. In addition, it is weakly linked to AppKit framework.
62 * Therefore it can be used to develop applications that don't require the graphical user interface.
63 */
64
65/**
66 * \defgroup descriptions Descriptions
67 * \ingroup baseten
68 * Database introspection.
69 */
70
71/**
72 * \defgroup auto_containers Self-updating collections
73 * \ingroup baseten
74 * Collections updated by the database context.
75 * The context will change the collection's contents according to its filter predicate
76 * after each relevant modification to the database.
77 */
78
79/**
80 * \mainpage Introduction
81 *
82 * BaseTen is a new, open source Cocoa database framework for working with PostgreSQL databases. BaseTen
83 * has been designed with familiar, Core Data -like semantics and APIs. With this 1.0 Release Candidate
84 * 2 version, a final 1.0 release is very near and it is safe to start development with the current BaseTen API.
85 *
86 * The BaseTen feature highlights include:
87 * \li BaseTen Assistant imports Core Data / Xcode data models
88 * \li Discovers the database schema automatically at runtime, including 1-1, 1-many and many-many relationships
89 * \li Database changes are propagated to clients automatically, without polling
90 * \li In-memory database objects are uniqued, and objects fetched via relationships are faults by default
91 * \li Support for RDBMS features like database-driven data validation, multi-column primary keys and updateable views
92 * \li Autocommit and manual save/rollback modes, both with NSUndoManager integration
93 * \li A BaseTen-aware NSArrayController subclass automates locking and change propagation
94 * \li Fetches are specified with NSPredicates (the relevant portions of which are evaluated on the database)
95 *
96 * \sa \ref general_usage
97 */
98
99/**
100 * \page general_usage Using BaseTen framework
101 *
102 * \li \subpage overview
103 * \li \subpage getting_started
104 * \li \subpage accessing_values
105 * \li \subpage tracking_changes
106 * \li \subpage using_appkit_classes
107 * \li \subpage postgresql_installation
108 * \li \subpage building_baseten
109 * \li \subpage limitations
110 */
111
112/**
113 * \page overview Overview of BaseTen
114 *
115 * \image html BaseTen-object-relationships.png "Relationships between BaseTen's objects"
116 * \image html BaseTen-class-hierarchy.png "BaseTen class hierarchy"
117 * \image latex BaseTen-object-relationships.pdf "Relationships between BaseTen's objects" width=\textwidth
118 * \image latex BaseTen-class-hierarchy.pdf "BaseTen class hierarchy" width=\textwidth
119 *
120 * BaseTen aims to provide a Core Data -like API for handling a database. A database connection is managed
121 * by an instance of BXDatabaseContext, which also fetches rows from the database. Rows are represented
122 * by instances of BXDatabaseObject. Objects are identified by
123 * \link BXDatabaseObjectID BXDatabaseObjectIDs\endlink, that are created using
124 * tables' primary keys. Foreign keys are interpreted as relationships between objects.
125 *
126 * Like some other object-relational mappers, BaseTen fetches the data model from the database.
127 * There are classes available for database introspection: BXEntityDescription, BXAttributeDescription,
128 * BXRelationshipDescription and its subclasses.
129 *
130 * Database objects are retrieved using an instance of BXDatabaseContext. The rows are specified using
131 * instances of BXEntityDescription and NSPredicate. This pattern should match most use cases. It is also
132 * possible to fetch rows as NSDictionaries by specifying an SQL query.
133 *
134 * Unlike the typical use case of Core Data, multiple users might be connected to the database being
135 * accessed using BaseTen. Thus, data manipulated with database objects could change at any time. BaseTen
136 * copes with this situation by updating objects' contents as soon as other database clients commit their
137 * changes. The other clients needn't use BaseTen.
138 *
139 * Instead of constantly polling the database for changes, BaseTen listens for PostgreSQL notifications.
140 * It then queries the database about the notification type and faults the relevant objects. For this to
141 * work, certain tables, views and functions need to be created in the database. The easiest way to do this
142 * is to connect to the database with BaseTen Assistant. Using it, relations may be enabled for use with
143 * the framework. Everything will be installed or will reference to a database schema called baseten, so
144 * removal, if needed, will be an easy process. BaseTen can connect to databases without the schema, but
145 * in this case functionality will be limited.
146 *
147 * Since BaseTen relies on database introspection, SQL may be used to define the database schema.
148 * Another option is to create a data model using Xcode's data modeler and import it using BaseTen Assistant.
149 *
150 * \see \subpage sql_views
151 * \see \subpage baseten_enabling
152 */
153
154/**
155 * \page sql_views SQL views
156 *
157 * Contents of SQL views may be manipulated using database objects provided that some conditions are met.
158 * Unlike tables, views don't have primary keys but BaseTen still needs to be able to reference individual
159 * rows. If a view has a group of columns that can act as a primary key, the columns may be marked as a
160 * primary key with the assistant, after which the view may be enabled.
161 *
162 * Views also lack foreign keys. Despite this entities that correspond to views may have relationships
163 * provided that a certain condition is met: the view needs to have the column or columns of an underlying
164 * table that form a foreign key, and the columns' names need to match. In this case, relationships will
165 * be created between the view and the target table as well as the view and all the views that are based
166 * on the target table and contain the columns the foreign key references to. This applies to the complete
167 * view hierarchy.
168 *
169 * PostgreSQL allows INSERT and UPDATE queries to target views if rules have been created to handle them.
170 * In this case, the view contents may be modified also with BaseTen.
171 */
172
173/**
174 * \page baseten_enabling More detail on enabling relations
175 *
176 * Some tables are created in BaseTen schema to track changes in other relations. The tables and relations
177 * correspond to each other based on their names. The BaseTen tables store values for the actual relations'
178 * primary keys. Thus, there will be two restrictions on table handling:
179 * \li Renaming tables after having them enabled will not work.
180 *     Should tables need to be renamed, first disable the table, then rename it and finally prepare it again.
181 * \li Changing tables' primary keys after having them enabled will not work. Use the method
182 *     described above.
183 *
184 * In addition to using BaseTen Assistant, it is possible to enable and disable tables with SQL functions.
185 * The functions are <em>baseten.prepareformodificationobserving</em> and <em>baseten.cancelmodificationobserving</em>
186 * and they take an oid as an argument.
187 *
188 * Views' primary keys are stored in <em>baseten.viewprimarykey</em>. The table has three columns: \em nspname,
189 * \em relname and \em attname, which correspond to the view's schema name, the view's name and each primary
190 * key column's name respectively. They also make up the table's primary key. In addition to using
191 * BaseTen Assistant, it is possible to determine a view's primary key by inserting rows into the table.
192 *
193 * Relationships that involve views are stored in automatically-generated tables. These may be refreshed view
194 * the SQL function <em>baseten.refreshcaches</em>. BaseTen Assistant does this automatically.
195 */
196
197/**
198 * \page getting_started Getting started
199 *
200 * Typically accessing a database consists roughly of the following steps:
201 * <ul>
202 *     <li>\subpage creating_a_database_context "Creating an instance of BXDatabaseContext"</li>
203 *     <li>\subpage connecting_to_a_database "Connecting to a database"</li>
204 *     <li>\subpage getting_an_entity_and_a_predicate "Getting an entity description from the context"</li>
205 *     <li>\subpage getting_an_entity_and_a_predicate "Possibly creating an NSPredicate for reducing the number of fetched objects"</li>
206 *     <li>\subpage performing_a_fetch "Performing a fetch using the entity and the predicate"</li>
207 *     <li>\subpage handling_the_results "Handling the results"</li>
208 * </ul>
209 * Here is a small walkthrough with sample code.
210 *
211 * \latexonly
212 * \lstset{language=[Objective]C, backgroundcolor=\color[rgb]{0.84,0.87,0.90}, rulecolor=\color[gray]{0.53}}
213 * \begin{lstlisting}[fontadjust, columns=fullflexible, float=h, frame=single, caption=A simple command line tool that uses BaseTen]
214 * #import <Foundation/Foundation.h>
215 * #import <BaseTen/BaseTen.h>
216 *
217 * int main (int argc, char** argv)
218 * {
219 *     NSURL* databaseURI = [NSURL URLWithString: @"pgsql://username@localhost/database"];
220 *     BXDatabaseContext* ctx = [[BXDatabaseContext alloc] initWithDatabaseURI: databaseURI];
221 *
222 *     [ctx connectSync: NULL];
223 *     BXEntityDescription* entity = [ctx entityForTable: @"table" error: NULL];
224 *     NSArray* result = [ctx executeFetchForEntity: entity predicate: nil error: NULL];
225 *
226 *     for (BXDatabaseObject* object in result)
227 *     {
228 *         NSLog (@"Object ID: %@ column: %@",
229 *                [[object objectID] URIRepresentation], [object valueForKey: @"column"]);
230 *     }
231 *
232 *     return 0;
233 * }
234 * \end{lstlisting}
235 * \endlatexonly
236 * \htmlonly
237 * <pre> #import <Foundation/Foundation.h>
238 * #import <BaseTen/BaseTen.h>
239 *
240 * int main (int argc, char** argv)
241 * {
242 *     NSURL* databaseURI = [NSURL URLWithString: @"pgsql://username@localhost/database"];
243 *     BXDatabaseContext* ctx = [[BXDatabaseContext alloc] initWithDatabaseURI: databaseURI];
244 *
245 *     [ctx connectSync: NULL];
246 *     BXEntityDescription* entity = [ctx entityForTable: @"table" error: NULL];
247 *     NSArray* result = [ctx executeFetchForEntity: entity predicate: nil error: NULL];
248 *
249 *     for (BXDatabaseObject* object in result)
250 *     {
251 *         NSLog (@"Object ID: %@ column: %@",
252 *                [[object objectID] URIRepresentation], [object valueForKey: @"column"]);
253 *     }
254 *
255 *     return 0;
256 * }</pre>
257 * \endhtmlonly
258 */
259 
260/**
261 * \page creating_a_database_context Creating a database context
262 *
263 * The designated initializer of BXDatabaseContext is <tt>-initWithDatabaseURI:</tt>. <tt>-init</tt> is also
264 * available but the context does require an URI before connecting.
265 *
266 * BXDatabaseContext requires the URI to be formatted as follows:
267 * <tt>pgsql://username:password\@host/database_name</tt>. Currently, as PostgreSQL is the only supported
268 * database, only <tt>pgsql://</tt> URIs are allowed. All parameters are required except for the password,
269 * the need for which depends on the database configuration.
270 *
271 * Various methods in BXDatabaseContext take a double pointer to an NSError object as a parameter. if the
272 * called method fails, the NSError will be set on return. If the parameter is NULL, the default error
273 * handler raises a BXException. BXDatabaseContext's delegate may change this behaviour.
274 */
275
276/**
277 * \page connecting_to_a_database Connecting to a database
278 *
279 * \latexonly
280 * \begin{lstlisting}[fontadjust, columns=fullflexible, float=h, frame=single, title=Connecting to a database]
281 * [ctx connectSync: NULL];
282 * \end{lstlisting}
283 * \endlatexonly
284 * \htmlonly
285 * <pre>[ctx connectSync: NULL];</pre>
286 * \endhtmlonly
287 *
288 *
289 * Connection to the database may be made synchronously using the method
290 * <tt>-connectSync:</tt>. Applications that use an NSRunLoop also have the
291 * option to use <tt>-connectAsync</tt>. The method returns immediately. When the connection attempt has
292 * finished, the context's delegate will be called and notifications will
293 * be posted to the context's notification center (accessed with <tt>-notificationCenter</tt>).
294 *
295 * In AppKit applications, the easiest way to connect to the database is to use the IBAction
296 * <tt>-connect:</tt>. In addition to attempting the connection asynchronously,
297 * it also presents a number of panels to the user, if some required information is missing from the URI.
298 * The panels allow the user to specify their username, password and the database host making URIs
299 * like <tt>pgsql:///database_name</tt> allowed. Additionally a \em kBXConnectionSetupAlertDidEndNotification
300 * will be posted when the user dismisses an alert panel, which is presented on failure.
301 *
302 * Since \em NULL is passed in place of an NSError double pointer, a BXException will be thrown on error.
303 * See BXDatabaseContext's documentation for details on error handling.
304 */
305
306/**
307 * \page getting_an_entity_and_a_predicate Getting a BXEntityDescription and an NSPredicate
308 *
309 * \latexonly
310 * \begin{lstlisting}[fontadjust, columns=fullflexible, float=h, frame=single, title=Getting a BXEntityDescription]
311 * BXEntityDescription* entity = [ctx entityForTable: @"table" error: NULL];
312 * \end{lstlisting}
313 * \endlatexonly
314 * \htmlonly
315 * <pre>BXEntityDescription* entity = [ctx entityForTable: @"table" error: NULL];</pre>
316 * \endhtmlonly
317 *
318 * BXEntityDescriptions are used to specify tables for fetches. For getting a specific
319 * entity description, BXDatabaseContext has two methods: <tt>-entityForTable:error:</tt> and
320 * <tt>-entityForTable:inSchema:error:</tt>. Entity descriptions may be accessed before making a
321 * connection in which case the database context will check their existence on connect.
322 *
323 * NSPredicates are created by various Cocoa objects and may be passed directly to BXDatabaseContext.
324 * One way to create ad-hoc predicates is by using <tt>-[NSPredicate predicateWithFormat]</tt>.
325 * In this example, we fetch all the objects instead of filtering them, though.
326 */
327
328/**
329 * \page performing_a_fetch Performing a fetch using the entity and the predicate
330 *
331 * \latexonly
332 * \begin{lstlisting}[fontadjust, columns=fullflexible, float=h, frame=single, title=Performing a fetch]
333 * NSArray* result = [ctx executeFetchForEntity: entity predicate: nil error: NULL];
334 * \end{lstlisting}
335 * \endlatexonly
336 * \htmlonly
337 * <pre>NSArray* result = [ctx executeFetchForEntity: entity predicate: nil error: NULL];</pre>
338 * \latexonly \caption{Getting a BXEntityDescription} \end{table} \endlatexonly
339 *
340 * BXDatabaseContext's method <tt>-executeFetchForEntity:withPredicate:error:</tt> and its variations may
341 * be used to fetch objects from the database. The method takes a BXEntityDescription and an NSPredicate and
342 * performs a fetch synchronously. The fetched objects are returned in an NSArray.
343 */
344
345/**
346 * \page handling_the_results Handling the results
347 *
348 * \latexonly
349 * \begin{lstlisting}[fontadjust, columns=fullflexible, float=h, frame=single, title=Handling fetch results]
350 * for (BXDatabaseObject* object in result)
351 * {
352 *    NSLog (@"Object ID: %@ column: %@",
353 *           [[object objectID] URIRepresentation], [object valueForKey: @"column"]);
354 * }
355 * \end{lstlisting}
356 * \endlatexonly
357 * \htmlonly
358 * <pre>for (BXDatabaseObject* object in result)
359 *{
360 *    NSLog (@"Object ID: %@ column: %@",
361 *           [[object objectID] URIRepresentation], [object valueForKey: @"column"]);
362 *}</pre>
363 * \endhtmlonly
364 *
365 * Since BXDatabaseObject conforms to \em NSKeyValueObserving, methods <tt>-valueForKey:</tt> and
366 * <tt>-setValue:forKey:</tt> are available. See \ref accessing_values for details.
367 */
368
369/**
370 * \page accessing_values Accessing object values
371 *
372 * BXDatabaseObjects implement NSKeyValueCoding and object values may thus be accessed with
373 * <tt>-valueForKey:</tt> and <tt>-setValue:forKey:</tt>. The key will be the column name. As with
374 * NSManagedObject, methods like <tt>-&lt;key&gt;</tt> and <tt>-set&lt;Key&gt;:</tt> are also automatically available.
375 *
376 * Column values are converted to Foundation objects based on the column type. The type conversion is
377 * defined in the file <em>datatypeassociations.plist</em>. Currently, there is no way to affect the type conversion,
378 * and modifying the file is not recommended. Instead, custom getters may be written for preprocessing
379 * fetched objects. To support this, the column values may also be accessed using
380 * <tt>-primitiveValueForKey:</tt>. Similarly <tt>-setPrimitiveValue:forKey:</tt> may be used to set a column
381 * value.
382 *
383 *
384 * \subsection accessing_relationships Accessing relationships
385 *
386 * BaseTen supports the same types of relationships as Core Data: one-to-one, one-to-many and many-to-many.
387 *
388 * One-to-many is the simplest type of these three: a foreign key in one table referring another will be
389 * interpreted as such. Both of the tables need to be BaseTen enabled and BaseTen's cache tables need to be
390 * up-to-date (see the BaseTen Assistant for details). Calling a database object's <tt>-valueForKey:</tt> or
391 * <tt>-primitiveValueForKey:</tt> on the to-one side with the name of the foreign key constraint will
392 * return the object on the other side of the reference. On the to-many side, -valueForKey: retrieves a
393 * collection of objects that reference the table in a foreign key. They key used is the other table's name.
394 *
395 * Consider the following example:
396 * <pre>CREATE TABLE person (
397 *    id SERIAL PRIMARY KEY,
398 *    firstname VARCHAR (255),
399 *    surname VARCHAR (255)
400 *);
401 *
402 *CREATE TABLE email (
403 *    id SERIAL PRIMARY KEY,
404 *    address VARCHAR (255),
405 *    person_id INTEGER CONSTRAINT person REFERENCES person (id)
406 *);</pre>
407 *
408 * Lets say we have two objects: \em aPerson and \em anEmail which have been fetched from the person and email
409 * tables, respectively. <tt>[aPerson valueForKey: @"email"]</tt> will now return a collection of \em email objects.
410 * <tt>[anEmail valueForKey: @"person"]</tt> will return a single \em person object.
411 *
412 * If we modify the previous example, we get a one-to-one relationship:
413 * <pre>ALTER TABLE email ADD UNIQUE (person_id);</pre>
414 * Now both <tt>[aPerson valueForKey: @"email"]</tt>
415 * and <tt>[anEmail valueForKey: @"person"]</tt> will return a single object from the corresponding table.
416 *
417 * Many-to-many relationships are modeled with helper tables. The helper table needs to have columns to contain
418 * both tables' primary keys. It needs to be BaseTen enabled as well.
419 *
420 * Another example:
421 *<pre>CREATE TABLE person (
422 *    id SERIAL PRIMARY KEY,
423 *    firstname VARCHAR (255),
424 *    surname VARCHAR (255)
425 *);
426 *
427 *CREATE TABLE title (
428 *    id SERIAL PRIMARY KEY,
429 *    name VARCHAR (255)
430 *);
431 *
432 *CREATE TABLE person_title_rel (
433 *    person_id INTEGER REFERENCES person (id),
434 *    title_id INTEGER REFERENCES title (id),
435 *    PRIMARY KEY (person_id, title_id)
436 *);</pre>
437 *
438 * Lets say \em aPerson has been fetched from the person table and \em aTitle from the title table.
439 * In this case, <tt>[aPerson valueForKey: @"title"]</tt> will return a collection of title objects
440 * and <tt>[aTitle valueForKey: @"person"]</tt> a collection of person objects. Any two foreign keys
441 * in one table will be interpreted as a many-to-many relationship, if they also form the table's
442 * primary key. Objects from the helper table may be retrieved as with one-to-many relationships:
443 * <tt>[aPerson valueForKey: @"person_title_rel"]</tt>.
444 *
445 *
446 * \subsubsection relationship_naming_conflicts Naming conflicts
447 *
448 * Referencing relationships with target table names works as long as there are only one foreign key in
449 * a given table referencing another. As the number increases, relationships obviously cannot be
450 * referenced using the target table name in every case. The following table describes alternative
451 * names for relationships in specific cases.
452 *
453 * <table>
454 *     <caption>Relationship names</caption>
455 *     <tr>
456 *         <th><strong>Relationship type</strong></th>
457 *         <th><strong>Target relation kind</strong></th>
458 *         <th><strong>Available names</strong></th>
459 *     </tr>
460 *     <tr>
461 *         <td rowspan="2">One-to-many (inverse, from the foreign key's side)</td>
462 *         <td>Table</td>
463 *         <td>Target table's name, foreign key's name</td>
464 *     </tr>
465 *     <tr>
466 *         <td>View</td>
467 *         <td>Target view's name</td>
468 *     </tr>
469 *     <tr>
470 *         <td rowspan="2">One-to-many (from the referenced side)</td>
471 *         <td>Table</td>
472 *         <td>Target table's name, <em>schema_table_foreignkey</em></td>
473 *     </tr>
474 *     <tr>
475 *         <td>View</td>
476 *         <td>Target view's name</td>
477 *     </tr>
478 *     <tr>
479 *         <td rowspan="2">One-to-one (from the foreign key's side)</td>
480 *         <td>Table</td>
481 *         <td>Target table's name, foreign key's name</td>
482 *     </tr>
483 *     <tr>
484 *         <td>View</td>
485 *         <td>Target view's name</td>
486 *     </tr>
487 *     <tr>
488 *         <td rowspan="2">One-to-one (from the referenced side)</td>
489 *         <td>Table</td>
490 *         <td>Target table's name, <em>schema_table_foreignkey</em></td>
491 *     </tr>
492 *     <tr>
493 *         <td>View</td>
494 *         <td>Target view's name</td>
495 *     </tr>
496 *     <tr>
497 *         <td rowspan="2">Many-to-many</td>
498 *         <td>Table</td>
499 *         <td>Target table's name, name of the foreign key that references the target table</td>
500 *     </tr>
501 *     <tr>
502 *         <td>View</td>
503 *         <td>Target view's name</td>
504 *     </tr>
505 * </table>
506 */
507
508/**
509 * \page tracking_changes Tracking database changes
510 *
511 * BXDatabaseObject conforms to NSKeyValueObserving and uses self-updating collections for storing
512 * related objects; changes in them may thus be tracked with KVO.
513 *
514 * BXSynchronizedArrayController's contents will be updated automatically. BXDatabaseContext's fetch
515 * methods also have the option to return a self-updating array instead of an
516 * ordinary one. In this case, the collection's owner has to be specified for KVO notifications to be posted.
517 * See the collection classes' documentation for details.
518 *
519 * Another, a more low-level means of tracking changes is observing NSNotifications. Notifications on
520 * entity changes will be posted to the relevant context's notification center. The notification object
521 * will be a BXEntityDescription which corresponds to the table where the change happened. The names
522 * of the notifications are:
523 * \li \c kBXInsertNotification on database \c INSERT
524 * \li \c kBXUpdateNotification on database \c UPDATE
525 * \li \c kBXDeleteNotification on database \c DELETE
526 *
527 * At the time the notifications are posted, database objects and self-updating collections will
528 * already have been updated.
529 */
530
531/**
532 * \page using_appkit_classes Using the controller subclasses provided with the framework
533 *
534 * BXDatabaseObjects may be used much in the same manner as NSManagedObjects to populate various Cocoa views. However,
535 * the initial fetch needs to be performed and the controller has to assigned the result set. To facilitate this,
536 * some NSController subclasses have been provided with the framework. For now, the only directly usable one is
537 * BXSynchronizedArrayController. Additionally, there is BXController and additions to NSController for creating
538 * controller subclasses.
539 *
540 *
541 * \subsection using_bxsynchronizedarraycontroller Using BXSyncronizedArrayController from Interface Builder
542 *
543 * <ol>
544 *     <li>Load the BaseTen plug-in or palette.</li>
545 *     <li>Create a new nib file.</li>
546 *     <li>Drag a database context and an array controller from the BaseTen palette to the file.</li>
547 *     <li>Select the database context and choose Attributes from the inspector's pop-up menu.</li>
548 *     <li>Enter a valid database URI.
549 *         <ul>
550 *             <li>If autocommit is selected from the context settings, the changes will be propagated immediately and
551 *                 undo affects most operations but not all. Otherwise, the context's -save: and -revert: methods
552 *                 should be used to commit and rollback. Undo may be used between commits.</li>
553 *         </ul>
554 *     </li>
555 *     <li>Select the array controller and choose Attributes from the inspector's pop-up menu.</li>
556 *     <li>Enter a table name into the field.
557 *         <ul>
558 *             <li>The schema field may be left empty, in which case <tt>public</tt> will be used.</li>
559 *             <li>Please note that the table needs to be enabled for change observing. This can be
560 *                 done using the Setup Application.</li>
561 *         </ul>
562 *     </li>
563 *     <li>Bind the Cocoa views to the controller.</li>
564 *     <li>Test the interface. The views should be populated using the database.</li>
565 * </ol>
566 */
567
568/**
569 * \page postgresql_installation PostgreSQL installation
570 *
571 * Here's a brief tutorial on PostgreSQL installation.
572 * <ol>
573 *     <li>Get the latest PostgreSQL source release (8.2 or later) from http://www.postgresql.org/ftp/source.</li>
574 *     <li>Uncompress, configure, make, [sudo] make install. On Mac OS X, Bonjour and OpenSSL are available, so <tt>./configure --with-bonjour --with-openssl && make && sudo make install</tt> probably gives the expected results.</li>
575 *     <li>It's usually a good idea to create a separate user and group for PostgreSQL, but Mac OS X already comes with a database-specific user: for mysql. We'll just use that and hope PostgreSQL doesn't mind.</li>
576 *     <li>Make <tt>mysql</tt> the owner of the PostgreSQL folder, then sudo to <tt>mysql</tt>:\n
577 *         <tt>
578 *             sudo chown -R mysql:mysql /usr/local/pgsql\n
579 *             sudo -u mysql -s
580 *         </tt>
581 *     </li>
582 *     <li>Initialize the PostgreSQL database folder. We'll use en_US.UTF-8 as the default locale:\n<tt>LC_ALL=en_US.UTF-8 /usr/local/pgsql/bin/initdb -D \\\n /usr/local/pgsql/data</tt></li>
583 *     <li>Launch the PostgreSQL server itself:\n
584 *         <tt>
585 *             /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data \\\n
586 *             -l /usr/local/pgsql/data/pg.log start
587 *         </tt>
588 *     <li>Create a superuser account for yourself. This way, you don't have to sudo to mysql to create new databases and users.\n
589 *         <tt>/usr/local/pgsql/bin/createuser <your-short-user-name></tt>
590 *     </li>
591 *     <li>Exit the <tt>mysql</tt> sudo and create a database. If you create a database with your short user name, psql will connect to it by default.\n
592 *         <tt>
593 *             exit\n
594 *             /usr/local/pgsql/bin/createdb <your-short-user-name>
595 *         </tt>
596 *     </li>
597 * </ol>
598 */
599
600/**
601 * \page building_baseten Building BaseTen
602 *
603 * For a successful build, Xcode 3.1 and Mac OS X 10.5 SDK are required.
604 *
605 * BaseTen has several subprojects, namely BaseTenAppKit and a plug-in for Interface Builder 3. The default target in
606 * BaseTen.xcodeproj, <em>BaseTen + GC</em>, builds them as well; the plug-in and the AppKit framework will appear in the
607 * subprojects' build folders, which are set to the default folder. The built files will be either in
608 * \em build folders in the subprojects' folders or in the user-specified build folder. The documentation will be
609 * in the \em Documentation folder.
610 *
611 *
612 * \subsection Building for the release DMG
613 *
614 * The files needed to build the release disk image are in the SVN repository as well. Doxygen is needed during
615 * the process. To create the DMG, follow these steps:
616 * <ol>
617 *     <li>From the checked-out directory, <tt>cd ReleaseDMG</tt>.</li>
618 *     <li>The default location for the built files is <em>~/Build/BaseTen-dmg-build</em>. To set a custom path, edit the \em SYMROOT variable in <em>create_release_dmg.sh</em>.</li>
619 *     <li>
620 *         Do <tt>./create_release_dmg.sh</tt>. The build DMG will appear in the ReleaseDMG folder.
621 *         <ul>
622 *             <li>If you don't have LaTeX installed, do <tt>./create_release_dmg.sh --without-latex</tt> instead. The PDF manual won't be included on the DMG, though.</li>
623 *         </ul>
624 *     </li>
625 * </ol>
626 */
627
628/**
629 * \page limitations Limitations in current version
630 *
631 * These are some of the most severe limitations in the current version.
632 * \li Practically all public classes are non-thread-safe, so thread safety must be enforced externally if it's required.
633 *     Furthermore, all queries must be performed from the thread in which the context made a database connection. This could change
634 *     in the future, so it is best to create and handle a context only in one thread.
635 * \li Any serialization mechanism has not been implemented for BXDatabaseObject.
636 * \li BaseTen is currently suitable for inserting small data sets into the database.
637 *     Insertion of larger data sets (thousands of objects) takes considerable amount of time and
638 *     may cause 'out of shared memory' errors if executed without the autocommit flag.
639 *     Fetching large data sets should be fast enough. 
640 * \li Currently, migration models aren't understood by the assistant, so the easiest way to do model
641 *         migration might be using SQL.
642 */
Note: See TracBrowser for help on using the browser.