Open Source Content Management Framework

mRFC 0049: mgdschema and namespaces

  1. Revision History
  2. PROBLEM
  3. SOLUTION
    1. schema:
    2. python:
    3. php 5.3+:
    4. php 5.2:

Revision History

  • 2010-01-10, created by Alexey Zakhlestin and Jarkko Ala-Louvesniemi

PROBLEM

Modern programming languages have concept of namespaces within them. Midgard, historically, used underscores as pseudo-namespacing tool, but these days we try to use real namespaces in python (and in php soon). Using namespaces in python led to the following code:

obj = midgard.mgdschema.midgard_article()

This code mentions "midgard" 2 times which doesn't look nice. Direct approach to fixing this leads to bad hacks and breaks backwards compatibility. See bug #1559 as an example. It removes midgard_ prefix from all type-names, which can result in names-conflict if there is some type which had the unprefixed name. Clearly a fully designed approach is needed because the API can't change in every Midgard release and we can't support multiple legacy syntaxes.

This document is a proposal for discussion on implementation, which would work as the long-term solution for all future language bindings.

SOLUTION

We propose to add explicit <namespace> tag in schema declaration file. Namespaces are supposed to have <class> tags as their children. On the side of language binding it might be translated either to true namespaces (python, php-5.3, etc.) or in pseudo-namespaces (php-5.2) depending on what binding author want/can do. For namespace-capable bindings we propose to use midgard.schema as the root namespace for everything.

It is recommended to prefix table names with namespace_. It shouldn't be enforced, but as a recommended practice would prevent table name conflicts and ease database-management (all tables would be grouped by component, if listed alphabetically). "table" attribute of <class> tag is optional (if left out, table name would be namespace_class) and it is recommended to leave it unset (less coupling between code and actual database implementation).

For backwards compatibility reasons, old syntax with missing namespace tags and <type> tags should still be supported. In this case class should be put in midgard.mgdschema (note that it is mgdschema, not schema as in first clause) namespace. This is a strictly backwards-compatibility option. Such files must not be distributed with Ratatoskr.

schema:

<namespace name="core">
    <class name="host" table="core_host">
        …
    </class>

    …
</namespace>

<namespace name="my_component">
    <class name="host" table="my_component_host">
        …
    </class>

    …
</namespace>

And compatibility mode:

<!-- Compatibility example -->
<type name="midgard_host" table="host>
    …
</type>

<type name="my_component_host" table="my_component_host">
        …
</type>
<!-- /Compatibility example -->

python:

obj = midgard.schema.core.host()
obj2 = midgard.schema.my_component.host()

# we can use class-name directly, instead of string. python allows it
qb = midgard.query_builder(midgard.schema.my_component.host)


# this should also work
from midgard.schema import core
from midgard.schema.my_component import *

obj = core.host()
obj2 = host()
qb = midgard.query_builder(core.host)
qb2 = midgard.query_builder(host)

and for "compatibility" mode:

obj = midgard.mgdschema.midgard_host()
obj2 = midgard.mgdschema.my_component_host()
qb = midgard.query_builder(midgard.mgdschema.my_component_host)

# string-parameter should work for "old schemas" in ratatoskr too (with deprecated-notice)
# (strings translate to classes under the midgard.mgdschema namespace only)
qb = midgard.query_builder('my_component_host')

php 5.3+:

$obj = new midgard\schema\core\host();
$obj2 = new midgard\schema\my_component\host();

// in php we can't pass class as parameter. have to use string.
// (use single quotes because with double quotes e.g. \n wouldn't work like expected)
$qb = new midgard\query_builder('midgard\schema\my_component\host');

// but this should work
$qb = midgard\schema\my_component\host::new_query_builder();


// and this
use midgard\schema\my_component as my;

$qb = my\host::new_query_builder();

and for "compatibility" mode:

$obj = new midgard_host();
$obj2 = new my_component_host();

$qb = new midgard_query_builder('my_component_host');
$qb2 = my_component_host::new_query_builder();

php 5.2:

if we continue to support php 5.2…

// "core" is represented as "midgard_" for historical reasons
$obj = new midgard_host();
$obj2 = new my_component_host();

$qb = new midgard_query_builder('my_component_host');
$qb2 = my_component_host::new_query_builder();

// "compatibility" mode translates to same API as above

Back

Designed by Nemein, hosted by Kafit