On Mon, Apr 01, 2013 at 02:35:35AM -0500, Anton Lavrik wrote:
> On Fri, Mar 29, 2013 at 7:38 AM, Motiejus Jakštys <
desir...@gmail.com> wrote:
> > On Fri, Mar 29, 2013 at 01:06:34AM -0500, Anton Lavrik wrote:
> >> On Thu, Mar 28, 2013 at 4:38 AM, Motiejus Jakštys <
desir...@gmail.com> wrote:
>
> I see. I would still claim that all that can be represented in .piqi.
> You can extend the Piqi language with your custom attributes and have
> the specs validated and converted to XML. Not sure if it would make
> things more practical for you, but syntactically it would arguably
> make specs look a lot nicer. If you are interested I can show you how
> to achieve this using a combination of "piqi cc" and "piqi compile"
> commands. In fact, this mechanism is already used in the new
> piqic_erang.erl -- see piqi-erlang/src/piqi.erlang.piqi as an example
> of the Piqi language extension.
You certainly have a point, but I don't know yet how complex it might
be.
> > I think you would be interested about this constraint mechanism.. Maybe
> > making it a side-by-side library of piqi. It integrates with piqi really
> > well, and does the 'constraints' that piqi is not designed to do.
>
> This sounds interesting. Can you give an example of how you define
> such constraints and how they are represented in the generated Erlang
> code?
An extract from our simplified example bucket definition:
<bucket>
<fieldlist>
<field tag="1" name="gid" type="types/gid" />
<field tag="2" name="given-name" type="string" >
<constraint name="length" max="255" />
</field>
<field tag="3" name="birthdate" type="types/date" null="true"
default="[.year 1990 .month 1 .day 1]">
<!-- Allow only 18 year 1 day+ persons -->
<constraint name="age_over" delta_months="5">
<param name="delta_years">18</param>
<param name="delta_days">1</param>
</constraint>
</field>
</fieldlist>
<gidconstraints>
<constraint name="unique"><field>email</field></constraint>
</gidconstraints>
<sql version="1"><![CDATA[
CREATE TABLE `demobucket` (
`gid` bigint(20) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`birthdate` varchar(10) NULL,
KEY `GID` (`GID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
]]>
</sql>
<sql version="2"><![CDATA[
CREATE TABLE `demobucket` (
`GID` bigint(20) unsigned NOT NULL,
`givenname` enum('m','f','u') NOT NULL,
`birthdate` date NOT NULL,
KEY `GID` (`GID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
]]>
</sql>
</bucket>
This gets converted to
.record [
.name demobucket
.field [ .name gid .type types/gid .code 1 ]
.field [ .name given-name .type string .code 2 ]
.field [ .name birthdate .type types/date .code 6 .optional
.default [.year 1990 .month 1 .day 1] ]
]
And
-define(TYPE_CONSTRAINTS, [
{'gid', 'types/gid', []},
{'given_name', 'string', []},
{'birthdate', 'types/date', [
{'null', <<"true">>},
{'default', <<"[.year 1990 .month 1 .day 1]">>}
]}
]
).
-define(FIELD_CONSTRAINTS, [
{'given_name', [ {'length', [ {'max', <<"255">>} ]} ]},
{'birthdate', [
{'age_over', [
{'delta_months', <<"5">>},
{'delta_years', <<"18">>},
{'delta_days', <<"1">>}
]}
]}
]
).
-define(GID_CONSTRAINTS, [ {'unique', ['email'], [] } ]).
Then there is some code to verify the constraints just behind our API
(in demobucket_piqi_impl.erl). Every constraint has its own function,
which does the validation. For example,
`bucket_type_constraints:length(Bin, Length)` returns `true` if `Bin`
has less than `Length` utf8 codepoints.
We also create a few SQL files (one per `version`), another .piqi file
suitable for piqi-rpc (get/update/delete and some more functions). As
you can imagine, it involves a fair number of Makefiles has a few moving
parts. If we see a way to reduce it in some non-complex way, we would
be happy with a cleaner second iteration.
I believe these type definitions could be extended, but I do not see an
immediate way to do that after reading piqi-erlang/doc/piqi-erlang.md.
Is it possible to extend the piqi language in the record definition
file?
Motiejus