• Aucun résultat trouvé

Creating a Table

Dans le document PHP OBJECT-ORIENTED (Page 162-165)

The SQL used to create the tblresources table in our database is shown in Listing 15-1.

CREATE TABLE tblresources(

id INTEGER PRIMARY KEY,

url VARCHAR(255) NOT NULL UNIQUE default '', email VARCHAR(70) NOT NULL default '',

precedingcopy VARCHAR(100) NOT NULL default '', linktext VARCHAR(255) NOT NULL default '', followingcopy VARCHAR(255) NOT NULL default '', target VARCHAR(35) default '_blank',

category VARCHAR(100) NOT NULL default '', theirlinkpage VARCHAR(100) default NULL, whenaltered TIMESTAMP default '0000-00-00', reviewed BOOLEAN default 0,

whenadded DATE default '2006-05-05');

Listing 15-1: Creating a table

Ex t en di ng SQL it e 143 Let’s have a look at the details.

To create a table with an autonumber field named id, the data type INTEGER is used in conjunction with PRIMARY KEY. This is equivalent to identifying a field as INTEGER auto_increment PRIMARY KEY in MySQL. In SQLite this field definition is the one exception to the rule that SQLite fields are typeless—otherwise all fields are strings. Creating fields as types other than string helps document the data types you are expecting but will not restrict the value entered. You can put a string into a float type field and a float into a Boolean. Further, specify-ing the length of a VARCHAR type field will not truncate data that exceeds the defined length. Any length of string can be entered into any field. Otherwise, the syntax for creating a table functions exactly as you might expect.

The field names used in creating this table are self-documenting, but a few comments are in order. A resource won’t be displayed until the reviewed field is set to true. The field with the data type TIMESTAMP whenaltered will be maintained using a trigger as will the whenadded field.

Views

Views are stored SELECT queries. If you repeatedly use the same query, it is worthwhile creating it as a view.

To make resource links easily accessible, let’s order them alphabetically and create hyperlinks to each letter of the alphabet. With this in mind, take a look at the alphabet view shown in Listing 15-2.

CREATE VIEW alphabet AS

SELECT DISTINCT UPPER(SUBSTR(linktext,1,1)) AS letter FROM tblresources

WHERE reviewed = 1 ORDER BY letter;

CREATE VIEW specific_link AS SELECT id, url,

(precedingcopy || ' ' || linktext || ' ' || followingcopy) AS copy

FROM tblresources;

Listing 15-2: Views

The alphabet view creates a row of links as pictured at the top of Figure 15-1.

Rather than repeat the SQL statement that makes up the alphabet view, we can instead simply SELECT * FROM alphabet using the name of the view in the FROM clause.

The second view, specific_link, also shown in Listing 15-2, demonstrates how a view can be “updated” when used in conjunction with a trigger. We will return to this view in the following discussion about triggers, but do note the use of || as the string concatenation operator.

As you can see, SQLite defines its own string manipulation functions. For a complete list of functions and operators, see www.sqlite.org/lang_expr.html.

Triggers

For those programmers who pride themselves on their laziness, triggers are a wonderful thing. By creating a trigger you can get maximum effect with mini-mum effort.

Triggers are activated by an INSERT, DELETE, or UPDATE SQL statement. They are often used to maintain referential integrity and avoid orphaned records—

for example, deleting an invoice might well trigger deletion of all related invoice items. We’re going to create three triggers for our application: one to mimic a timestamp field, another to show the advantages of laziness, and finally a trigger to demonstrate how a view can be “updated.”

The timestamp triggers are shown in Listing 15-3. They are activated whenever a record in the tblresources table is added or updated.

CREATE TRIGGER insert_resources AFTER INSERT ON tblresources BEGIN

UPDATE tblresources SET whenaltered = DATETIME('NOW','LOCALTIME') WHERE id = new.id;

END;

CREATE TRIGGER update_resources AFTER UPDATE ON tblresources BEGIN

UPDATE tblresources SET whenaltered = DATETIME('NOW','LOCALTIME') WHERE id = new.id;

END;

CREATE TRIGGER add_date AFTER INSERT ON tblresources BEGIN

UPDATE tblresources SET whenadded = DATE('NOW','LOCALTIME') WHERE id = new.id;

END;

CREATE TRIGGER delete_link INSTEAD OF DELETE ON specific_link FOR EACH ROW

BEGIN

DELETE FROM tblresources WHERE id = old.id;

END;

Listing 15-3: Triggers

There is no need to remember to update the whenaltered field each time a change is made to a record—the insert_resources and update_resources triggers will do this for you. The current date and time will be added in the background. Effectively, this field will now function like a MYSQL TIMESTAMP field.

Likewise with the add_date trigger, also shown in Listing 15-3. We want to highlight new links. This trigger makes it possible to capture the date a link is added. By using a trigger we don’t have to worry about forgetting to main-tain this field, and we don’t have to write additional code each time a record is added.

Ex t en di ng SQL it e 145 Creating a trigger on a view is a convenient way of performing an “update”

against a view. By themselves, views are not updatable. If you attempt to delete from a view that has no associated trigger, you’ll get a warning like the following:

Warning: SQLiteDatabase::query() [function.query]: cannot modify specific_link because it is a view...

We solved this problem in the trigger we created on the view specific_link shown in Listing 15-3. Because we used an INSTEAD OF clause, any attempt to delete from this view instead removes the appropriate record from the table, tblresources.

In this trigger we have specified FOR EACH ROW. Doing so is optional.

AFOR EACH STATEMENT clause also exists but is not yet supported.

The WHERE clause of a trigger is somewhat intuitive but may cause some confusion. Using new.id to specify a newly inserted record and old.id for a deleted record clearly makes sense. Either old or new may be used when a record is updated.

Using triggers is very convenient, although the same effect could be achieved programmatically. But because triggers are embedded in the data-base, they are activated even when you make changes from the command line. Triggers help maintain the integrity of your database when it is modified outside of your application. Laziness has its rewards.

Dans le document PHP OBJECT-ORIENTED (Page 162-165)