On Thursday, 4 April 2013 at 09:54:48 UTC, Dicebot wrote:
On Wednesday, 3 April 2013 at 19:07:39 UTC, Vadim Lopatin wrote:
I don't see what to simplify in markup like this:
...

You may implement approach similar to one used in vibe.d http.rest and http.form modules. Some specific examples are described by Jacob, but, in general, in results in 3 configuration stages: 0) No configuration at all, all data is inferred from variable names and types according to some sane convention. 1) Convention configuration - you chose one convention to use for aggregate type introspection at compile-time. Few different pre-defined conventions exist.
2) Fine configuration using UDAs.


Implemented changes for better convention-over-configuration:
- If no annotations on class level, @Entity is assumed.
- No required annotation for simple properties. Nullability is deduced from data type - @Embedded annotation is not needed anymore - it's deduced from field's class @Embeddable annotation - If no key field annotations specified in class (@Id, @Generated, @Generator) - property named "id" (if any) is considered to be a @Generated primary key.
- For Object fields @ManyToOne is applied by default
- For Object[] or LazyCollection!Object @OneToMany is applied by default
- @OneToOne and @ManyToOne are required, since cannot be deduced

Following declarations are valid (comments describe ):

// @Entity assumed since no @Embeddable annotation
class User {
   long id;         // @Generated deduced from field name
   string name;     // deduced @NotNull
Address address; // deduced @Embedded from annotation of Address
   Customer customer; // deduced @ManyToOne @JoinColumn
// annotation required, otherwise would be deduced as @OneToMany
   @ManyToMany Roles[] roles;
}

@Embeddable // required for Embeddable
class Address {
   String zip;           // @Null
   String state;         // @Null
   string streetAddress; // @NotNull
}

// @Entity assumed since no @Embeddable annotation
class Customer {
   int id;     // @Generated primary key - from field name
   string name;// @NotNull
   Long flags; // @Null - because it's Long - not long
   LazyCollection!User users; // @OneToMany by default
// annotation required, otherwise would be deduced as @ManyToOne
   // @JoinColumn is required on one of OneToOne sides
   @OneToOne @JoinColumn CustomerOptions customerOptions;
}

// @Entity assumed
class CustomerOptions {
   int id;
// annotation required, otherwise would be deduced as @ManyToOne
   @OneToOne Customer customer;
}

// @Entity assumed since no @Embeddable annotation
class Role {
   int id;      // @Generated
   string name; // @NotNull
// annotation required, otherwise would be deduced as @OneToMany
   @ManyToMany LazyCollection!User users;
}

Aliases added, to simple put uppercase Long instead of Nullable!long in code:
alias Nullable!byte Byte;
alias Nullable!ubyte Ubyte;
alias Nullable!short Short;
alias Nullable!ushort Ushort;
alias Nullable!int Int;
alias Nullable!uint Uint;
alias Nullable!long Long;
alias Nullable!ulong Ulong;
alias Nullable!float Float;
alias Nullable!double Double;
alias Nullable!DateTime NullableDateTime;
alias Nullable!Date NullableDate;
alias Nullable!TimeOfDay NullableTimeOfDay;

String (uppercase nullable version of string) is defined as struct wrapper around string field, with interface similar to Nullable! Looks ugly, but I tried `typedef string String`, but it is deprecated; `alias string String` cannot be distinguished from just string. How to define String better? Is there a good way to define String to be compatible with string, but with the ability to distinguish between string and String in compile time?

Reply via email to