CXXXIII. SDO Relational Data Access Service FunctionsIntroducción
In order to use the Relational Data Access Service for Service Data Objects, you will need to understand some of the concepts behind SDO: the data graph, the data object, the disconnected way of working, the change summary, XPath and property expressions, and so on. If you are not familiar with these ideas, you might want to look first at the section on SDO. In addition, the Relational DAS makes use of the PDO extension to isolate itself from specifics of different back-end relational databases. In order to use the Relational DAS you will need to be able to create and pass a PDO database connection; for this reason you might also want to take a look at the section on PDO. The job of the Relational DAS is to move data between the application and a relational database. In order to do this it needs to be told the mapping between the database entities - tables, columns, primary keys and foreign keys - and the elements of the SDO model - types, properties, containment relationships and so on. You specify this information as metadata when you construct the Relational DAS.
There are other ways of working with the data in the database: it is possible to just create data objects and write them to the database without a preliminary call to executeQuery(), for example. This scenario and others are explored in the Examples section below. InstalaciónThe installation instructions for all the SDO components are in the SDO install section of the SDO documentation. In any case, the essential facts are that the Relational DAS is written in PHP and it should be placed somewhere on the PHP include_path . Your application will of course need to include the Relational DAS with a statement like this:
RequisitosThe Relational DAS requires that the SDO extension be installed. The SDO extension requires a version of PHP 5.1, and the Relational DAS requires a recent version that contains an important fix for PDO. The most up-to-date information about required levels of PHP should be found in the changelog for the package on PECL. At the time of writing, though, the Relational DAS requires the most recent beta level of PHP 5.1, that is PHP 5.1.0b3. The Relational DAS uses PDO to access the relational database, and so should run with a variety of different relational databases. At the time of writing it has been tested in the following configurations
The Relational DAS applies changes to the database within a user-delimited transaction: that is, it issues a call to PDO::beginTransaction() before beginning to apply changes, and PDO::commit() or PDO::rollback() on completion. Whichever database is chosen, the database and the PDO driver for the database must support these calls. LimitationsThere are the following limitations in the current release of the Relational DAS:
EjemplosThis section illustrates how the Relational DAS can be used to create, retrieve, update and delete data in a relational database. Many of the examples are illustrated with a three-table database that contains companies, departments within those companies, and employees that work in those departments. This example is used in a number of places within the SDO literature. See the examples section of the Service Data Objects specification or the Examples section of the documentation for the SDO extension. The Relational DAS is constructed with metadata that defines the relational database and how it should be mapped to SDO. The long section that follows describes this metadata and how to construct the Relational DAS. The examples that follow it all assume that this metadata is in an included php file. The examples below and others can all be found in the Scenarios directory in the Relational DAS package. The Relational DAS throws exceptions in the event that it finds errors in the metadata or errors when executing SQL statements against the database. For brevity the examples below all omit the use of try/catch blocks around the calls to the Relational DAS. These examples all differ from the expected use of SDO in two important respects. First, they show all interactions with the database completed within one script. In this respect these scenarios are not realistic but are chosen to illustrate just the use of the Relational DAS. It is expected that interactions with the database will be separated in time and the data graph serialised and deserialised into the PHP session one or more times as the application interacts with an end user. Second, all queries executed against the database use hard-coded queries with no variables substituted. In this case it is safe to use the simple executeQuery() call, and this is what the examples illustrate. In practice, though, it is unlikely that the SQL statement is known entirely ahead of time. In order to allow variables to be safely substituted into the SQL queries, without running the risk of injecting SQL with unknown effects, it is safer to use the executePreparedQuery() which takes a prepared SQL statement containing placeholders and a list of values to be substituted. Specifying the metadataThis first long section describes in detail how the metadata describing the database and the required SDO model is supplied to the Relational DAS. When the constructor for the Relational DAS is invoked, it needs to be passed several pieces of information. The bulk of the information, passed as an associative array in the first argument to the constructor, tells the Relational DAS what it needs to know about the relational database. It describes the names of the tables, columns, primary keys and foreign keys. It should be fairly easy to understand what is required, and once written it can be placed in a php file and included when needed. The remainder of the information, passed in the second and third arguments to the constructor, tells the Relational DAS what it needs to know about the relationships between objects and the shape of the data graph; it ultimately determines how the data from the database is to be normalised into a graph. Database metadataThe first argument to the constructor describes the target relational database. Each table is described by an associative array with up to four keys.
This metadata corresponds to a relational database that might have been defined to MySQL as:
or to DB2 as:
Note that although in this example there are no foreign keys specified to the database and so the database is not expected to enforce referential integrity, the intention behind the co_id column on the department table and the dept_id column on the employee table is they should contain the primary key of their containing company or department record, respectively. So these two columns are acting as foreign keys. There is a third foreign key in this example, that from the employee_of_the_month column of the company record to a single row of the employee table. Note the difference in intent between this foreign key and the other two. The employee_of_the_month column represents a single-valued relationship: there can be only one employee of the month for a given company. The co_id and dept_id columns represent multi-valued relationships: a company can contain many departments and a department can contain many employees. This distinction will become evident when the remainder of the metadata picks out the company-department and department-employee relationships as containment relationships. There are a few simple rules to be followed when constructing the database metadata:
Given these rules, and given the SQL statements that define the database, the database metadata should be easy to construct. What the Relational DAS does with the metadataThe Relational DAS uses the database metadata to form most of the SDO model. For each table in the database metadata, an SDO type is defined. Each column which can represent a primitive value (columns which are not defined as foreign keys) are added as properties to the SDO type. All primitive properties are given a type of string in the SDO model, regardless of their SQL type. When writing values back to the database the Relational DAS will create SQL statements that treat the values as strings, and the database will convert them to the appropriate type. Foreign keys are interpreted in one of two ways, depending on the metadata in the third argument to the constructor that defines the SDO containment relationships. A discussion of this is therefore deferred until the section on SDO containment relationships below. Specifying the application root typeThe second argument to the constructor is the application root type. The true root of each data graph is an object of a special root type and all application data objects come somewhere below that. Of the various application types in the SDO model, one has to be the application type immediately below the root of the data graph. If there is only one table in the database metadata, the application root type can be inferred, and this argument can be omitted. Specifying the SDO containment relationshipsThe third argument to the constructor defines how the types in the model are to be linked together to form a graph. It identifies the parent-child relationships between the types which collectively form a graph. The relationships need to be supported by foreign keys to be found in the data, in a way shortly to be described. The metadata is an array containing one or more associative arrays, each of which identifies a parent and a child. The example below shows a parent-child relationship from company to department, and another from department to employee. Each of these will become an SDO property defining a multi-valued containment relationship in the SDO model.
Foreign keys in the database metadata are interpreted as properties with either multi-valued containment relationships or single-valued non-containment references, depending on whether they have a corresponding SDO containment relationship specified in the metadata. In the example here, the foreign keys from department to company (the co_id column in the department table) and from employee to department (the dept_id column in the employee table) are interpreted as supporting the SDO containment relationships. Each containment relationship mentioned in the SDO containment relationships metadata must have a corresponding foreign key present in the database and defined in the database metadata. The values of the foreign key columns for containment relationships do not appear in the data objects, instead each is represented by a containment relationship from the parent to the child. So the co_id column in the department row in the database, for example, does not appear as a property on the department type, but instead as a containment relationship called department on the company type. Note that the foreign key and the parent-child relationship appear to have opposite senses: the foreign key points from the department to the company, but the parent-child relationship points from company to department. The third foreign key in this example, the employee_of_the_month , is handled differently. This is not mentioned in the SDO containment relationships metadata. As a consequence this is interpreted in the second way: it becomes a single-valued non-containment reference on the company object, to which can be assigned references to SDO data objects of the employee type. It does appear as a property on the company type. The way to assign a value to it in the SDO data graph is to have a graph that contains an employee object through the containment relationships, and to assign the object to it. This is illustrated in the later examples below. One-table examplesThe following set of examples all use the Relational DAS to work with a data graph containing just one application data object, a single company and the data just to be found the company table. These examples do not exercise the power of SDO or the Relational DAS and of course the same result could be achieved more economically with direct SQL statements but they are intended to illustrate how to work with the Relational DAS. For this very simple scenario it would be possible to simplify the database metadata to include just the company table - if that were done the second and third arguments to the constructor and the column specifier used in the query example would become optional.
Two-table examplesThe following set of examples all use two tables from the company database: the company and department tables. These examples exercise more of the function of the Relational DAS. In this series of examples a company and department are created, retrieved, updated, and finally deleted. This illustrates the lifecycle for a data graph containing more than one object. Note that this example clears out the company and department tables at the start so that the exact results of the queries can be known. You can find these examples combined into one script called 1cd-CRUD in the Scenarios directory in the Relational DAS package.
Three-table exampleThe following examples use all three tables from the company database: the company, department, and employee tables. These introduce the final piece of function not exercised by the examples above: the non-containment reference employee_of_the_month. Like the examples above for company and department, this set of examples is intended to illustrate the full lifecycle of such a data graph.
TracingYou may be interested in seeing the SQL statements that are generated in order to apply changes back to the database. At the top of the SDO/DAS/Relational.php you will find a number of constants which control whether the process of constructing and executing the SQL statements is to be traced. Try setting DEBUG_EXECUTE_PLAN to TRUE to see the generated SQL statements. Clases predefinidasThe Relational DAS provides two classes: the Relational DAS itself and the subclass of Exception that can be thrown. The Relational DAS has four publicly useful calls: the constructor, the createRootDataObject() call to obtain the root object of an empty data graph, the executeQuery() call to obtain a data graph containing data from a relational database, and the applyChanges() call to write changes made to a data graph back to the relational database. SDO_DAS_RelationalThe only object other than an SDO_DAS_Relational_Exception with which the application is expected to interact. Métodos
SDO_DAS_Relational_ExceptionIs a subclass of PHP's Exception. It adds no behaviour to Exception. Thrown, with useful descriptive text, to signal errors in the metadata or unexpected failures to perform SQL operations.
|
|||||||||||||||||||||||||||||||||||||||||||||||