AXMLS database schema - default values and foreign

2019-09-07 02:30发布

I am developing a package for Concrete5 that uses AXMLS format to specify the database schema.

http://www.concrete5.org/documentation/how-tos/developers/creating-and-working-with-db-xml-files/

Here is the schema:

<?xml version="1.0"?>
<schema version="0.3">
    <table name="notificationCategory">
        <field name="id" type="I"> <!-- integer -->
            <key/>
            <autoincrement/>
        </field>

        <field name="name" type="C" size="255"> <!-- varchar(255) -->
        </field>

        <field name="created" type="T">
            <deftimestamp/>
        </field>

        <field name="modified" type="T">
        </field>

         <opt>
            Type=InnoDB
        </opt>
    </table>

     <table name="notificationEntry">
        <field name="id" type="I"> <!-- integer -->
            <key/>
            <autoincrement/>
        </field>

        <field name="name" type="C" size="255"> <!-- varchar(255) -->
        </field>

        <field name="cat_id" type="I">
        </field>

        <constraint>
            ADD CONSTRAINT `cat_id_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `notificationCategory`.(`id`) ON DELETE CASCADE 
        </constraint>

        <opt>
            Type=InnoDB
        </opt>
    </table>
</schema>

I am struggling with two things:

  • Foreign keys. The result of the following is a table NotificationEntry where foreign key does not get set (it is using InnoDB)

  • Default values for created and modified field. I want created to have a default value of the current date, while for modified I'd like to have ON UPDATE CURRENT_TIMESTAMP

          show create table notificationCategory;
    
      CREATE TABLE `notificationCategory` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(255) DEFAULT NULL,
       `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       `modified` datetime DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    

There is very little documentation available for this format, did anyone have success using it?

1条回答
Anthone
2楼-- · 2019-09-07 03:13

As per the MySQL documentation, you don't use ADD CONSTRAINT when you're creating the table: http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

Second, all <constraint> definitions need to be inside the <field> definitions as per ADOdb documentation: http://adodb.sourceforge.net/docs-datadict.htm

Additional constraints defined at the end of the field definition.

Third, the constraint definition needs a comma in front of it because it is concatenated at the end of the CREATE TABLE block so the generated MySQL would be invalid without the comma. I'm not sure whether this is documented anywhere but the PostgreSQL example on the ADOdb documentation page shows a comma in front of the statement.

So, your field definition and constraint should look like this:

<field name="catID" type="I">
  <constraint>
    , FOREIGN KEY (catID) REFERENCES NotificationsNotificationCategory(catID) ON DELETE CASCADE 
  </constraint>
</field>

And few more suggestions:

  • Follow the naming conventions for the database tables and columns set by the concrete5 core. You can easily figure these out by exploring the core database tables.
    • Table names in CamelCaseFormat (note the starting capital letter). Only exceptions to this rule are BlockType tables (starting with bt) and AttributeType tables (starting with at).
    • Name your primary key names following the core conventions. E.g. the primary key for the Collections table is cID and the primary key for the Files table is fID. Try to avoid possible conflicts with the core primary keys when naming your fields, e.g. instead of using "cID" as the name for your category table, use "catID" like you had already suggested.
    • Use camelCaseFormat (note the lower starting letter) also in the field names just like any other table in concrete5.
  • Always prefix the database table names with your package handle in CamelCased format. E.g. if your package's handle is "notifications", you would create database tables named NotificationsTableName

Following these conventions keeps your code clean and allows easy reading for any possible future developers that are already familiar with concrete5 and might explore your code. Although you would not agree with all the conventions, it is better to follow them than to let every developer reinvent the wheel every time.

查看更多
登录 后发表回答