comp.lang.ada
 help / color / mirror / Atom feed
* Design problem: generic package vs tagged subtype
@ 2010-06-30 17:52 Marek Janukowicz
  2010-06-30 19:23 ` Simon Wright
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Janukowicz @ 2010-06-30 17:52 UTC (permalink / raw)


Hello everyone

I'm struggling with some design problems in my project. To explain them I 
need to give some background on my project, so please bear with me.

I'm developing a library to wrap relational database records into Ada 
objects (this kind of libraries are usually called "ORMs"). Generally I need 
following entities:
- some type corresponding to database table (I called it "Model"). It's 
instances will hold records from that table, so it needs something to hold 
database column values as attributes. Operations generally need to be 
overridable.
- something to map relationships between tables (associations)

For Model I use a tagged type wrapped into generic package:
generic
   Tbl_Name : String;
   type Attribute_Type is (<>);
   type Attribute_Type_Array is array (Attribute_Type range <>) of 
Attribute_Type_Type;
   Attribute_Types : Attribute_Type_Array;
package Dar.Models.Base is
            
   type Model is abstract tagged limited record
...

For associations I also use a generic package:
generic 
   with package Source_Model is new Dar.Models.Base(<>);
   with package Target_Model is new Dar.Models.Base(<>);
   Foreign_Key : String;
package Dar.Models.Associations is
   function Find
...


Here's where the trouble begins. Those Model subtypes tend to have quite a 
lot of custom logic, some operations overriden etc. and I can't add this to 
generic package instantiation, so I instantiate Dar.Models.Base inside 
another package:

package Dar_Test.Models.Users is
   type Attribute_Type is (Id, Username, Email);
   type Attribute_Type_Array is array (Attribute_Type range <>) of 
Dar.Models.Attribute_Type_Type;
   package Base is new Dar.Models.Base(
      Tbl_Name => "authors",
      Attribute_Type => Attribute_Type,
      Attribute_Type_Array => Attribute_Type_Array,
      Attribute_Types => (
         Id => Attr_Integer,
         Username => Attr_String,
         Email => Attr_String
      )
   );
   (some additional operations)
   ...

What I don't like is that I have additional operations in Users package, but 
builtin operations in Users.Base (I want to make the design clean for 
programmers using my library). I don't like parametrizing Associations with 
Base instantiation. I think having just a tagged type (without a generic 
package Dar.Models.Base) and extending it would be better, but I don't know 
how to parametrize it with Attribute_Type type. 

I hope my description is not too vague. If you have any thoughts or think my 
approach is totally wrong please share your thoughts.

Two additional (small) questions:
1. I'd like to replace type Attribute_Type_Array is array (Attribute_Type 
range <>) of Attribute_Type_Type in Dar.Models.Base specification with ... 
array (Attribute_Type'Range) ... to make sure full range of Attribute_Type 
is specified, but the compiler complains. Is there any other way to ensure 
that?
2. I have a type Attribute_Type_Type used to specify types of attributes 
(Integer, Date, String etc.). I then have a variant record:
  type Attribute_Value( Attr_Type : Attribute_Type_Type ) is
      record
         case Attr_Type is
            when Attr_Date =>
               Date_Value : APQ_Date;
            when Attr_Time =>
               Time_Value : APQ_Time;
            ...
Is there any way to use builtin types here instead of Attr_Date, 
Attr_Integer, etc? Note that I need to specify type of each attribute in one 
array.

Thanks in advance for reading my lengthy post :)
-- 
Marek Janukowicz

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-06-30 17:52 Design problem: generic package vs tagged subtype Marek Janukowicz
@ 2010-06-30 19:23 ` Simon Wright
  2010-06-30 22:33   ` Marek Janukowicz
  0 siblings, 1 reply; 13+ messages in thread
From: Simon Wright @ 2010-06-30 19:23 UTC (permalink / raw)


Marek Janukowicz <marek@janukowicz.net> writes:

> Hello everyone
>
> I'm struggling with some design problems in my project. To explain them I 
> need to give some background on my project, so please bear with me.
>
> I'm developing a library to wrap relational database records into Ada 
> objects (this kind of libraries are usually called "ORMs"). Generally I need 
> following entities:
> - some type corresponding to database table (I called it "Model"). It's 
> instances will hold records from that table, so it needs something to hold 
> database column values as attributes. Operations generally need to be 
> overridable.
> - something to map relationships between tables (associations)
>
> For Model I use a tagged type wrapped into generic package:
> generic
>    Tbl_Name : String;
>    type Attribute_Type is (<>);
>    type Attribute_Type_Array is array (Attribute_Type range <>) of 

Does this have to be an unconstrained array? If it wasn't, you wouldn't
need to worry about whether Attribute_Types covered the range of
Attribute_Type.

> Attribute_Type_Type;
>    Attribute_Types : Attribute_Type_Array;
> package Dar.Models.Base is
>             
>    type Model is abstract tagged limited record

   type Model is new Abstract_Base with ...

> ...
>
> For associations I also use a generic package:
> generic 
>    with package Source_Model is new Dar.Models.Base(<>);
>    with package Target_Model is new Dar.Models.Base(<>);
>    Foreign_Key : String;
> package Dar.Models.Associations is
>    function Find
> ...

... then the association can be between objects of type
Abstract_Base_Class'Class (though I don't see how you'd express the
actual relationship, not clear how Foreign_Key enters the picture).

>
>
> Here's where the trouble begins. Those Model subtypes tend to have quite a 
> lot of custom logic, some operations overriden etc. and I can't add this to 
> generic package instantiation, so I instantiate Dar.Models.Base inside 
> another package:
>
> package Dar_Test.Models.Users is
>    type Attribute_Type is (Id, Username, Email);
>    type Attribute_Type_Array is array (Attribute_Type range <>) of 
> Dar.Models.Attribute_Type_Type;
>    package Base is new Dar.Models.Base(
>       Tbl_Name => "authors",
>       Attribute_Type => Attribute_Type,
>       Attribute_Type_Array => Attribute_Type_Array,
>       Attribute_Types => (
>          Id => Attr_Integer,
>          Username => Attr_String,
>          Email => Attr_String
>       )
>    );
>    (some additional operations)
>    ...
>
> What I don't like is that I have additional operations in Users package, but 
> builtin operations in Users.Base (I want to make the design clean for 
> programmers using my library). I don't like parametrizing Associations with 
> Base instantiation. I think having just a tagged type (without a generic 
> package Dar.Models.Base) and extending it would be better, but I don't know 
> how to parametrize it with Attribute_Type type. 
>
> I hope my description is not too vague. If you have any thoughts or think my 
> approach is totally wrong please share your thoughts.
>
> Two additional (small) questions:
> 1. I'd like to replace type Attribute_Type_Array is array (Attribute_Type 
> range <>) of Attribute_Type_Type in Dar.Models.Base specification with ... 
> array (Attribute_Type'Range) ... to make sure full range of Attribute_Type 
> is specified, but the compiler complains. Is there any other way to ensure 
> that?

See above for suggestion. And why not just "array (Attribute_Type)"?

> 2. I have a type Attribute_Type_Type used to specify types of attributes 
> (Integer, Date, String etc.). I then have a variant record:
>   type Attribute_Value( Attr_Type : Attribute_Type_Type ) is
>       record
>          case Attr_Type is
>             when Attr_Date =>
>                Date_Value : APQ_Date;
>             when Attr_Time =>
>                Time_Value : APQ_Time;
>             ...
> Is there any way to use builtin types here instead of Attr_Date, 
> Attr_Integer, etc? Note that I need to specify type of each attribute in one 
> array.

I don't believe so.

As a side note I really dislike the name Attribute_Type_Type. It seems
to me that what you've called Attribute_Type is much more like a Name
than a Type.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-06-30 19:23 ` Simon Wright
@ 2010-06-30 22:33   ` Marek Janukowicz
  2010-07-01  4:13     ` naming, was " tmoran
  2010-07-01  5:57     ` Simon Wright
  0 siblings, 2 replies; 13+ messages in thread
From: Marek Janukowicz @ 2010-06-30 22:33 UTC (permalink / raw)


Simon Wright wrote:
>> For Model I use a tagged type wrapped into generic package:
>> generic
>>    Tbl_Name : String;
>>    type Attribute_Type is (<>);
>>    type Attribute_Type_Array is array (Attribute_Type range <>) of
> 
> Does this have to be an unconstrained array? If it wasn't, you wouldn't
> need to worry about whether Attribute_Types covered the range of
> Attribute_Type.

The only reason it was an unconstrained array is that my Ada skills are 
extremely poor and I didn't know it would work this way :) I'm a bit lost in 
this subject in general: could anyone tell me the exact difference between:
- array (Attribute_Type)
- array (Attribute_Type range <>)
- array (Attribute_Type'Range)


>> Attribute_Type_Type;
>>    Attribute_Types : Attribute_Type_Array;
>> package Dar.Models.Base is
>>             
>>    type Model is abstract tagged limited record
> 
>    type Model is new Abstract_Base with ...
> 
>> ...
>>
>> For associations I also use a generic package:
>> generic
>>    with package Source_Model is new Dar.Models.Base(<>);
>>    with package Target_Model is new Dar.Models.Base(<>);
>>    Foreign_Key : String;
>> package Dar.Models.Associations is
>>    function Find
>> ...
> 
> ... then the association can be between objects of type
> Abstract_Base_Class'Class (though I don't see how you'd express the
> actual relationship, not clear how Foreign_Key enters the picture).

That's how I really have it implemented, didn't want to go that much into 
the details. Generally, I need to figure out what's really my problem here 
and then ask again :)

>> 2. I have a type Attribute_Type_Type used to specify types of attributes
>> (Integer, Date, String etc.). I then have a variant record:
>>   type Attribute_Value( Attr_Type : Attribute_Type_Type ) is
>>       record
>>          case Attr_Type is
>>             when Attr_Date =>
>>                Date_Value : APQ_Date;
>>             when Attr_Time =>
>>                Time_Value : APQ_Time;
>>             ...
>> Is there any way to use builtin types here instead of Attr_Date,
>> Attr_Integer, etc? Note that I need to specify type of each attribute in
>> one array.
> 
> I don't believe so.
> 
> As a side note I really dislike the name Attribute_Type_Type. It seems
> to me that what you've called Attribute_Type is much more like a Name
> than a Type.

Yeah, you might be right on that. I still need to find out what a good 
naming convention would be. I wouldn't like to use:

type Attribute_Name_Type is (Id, Username, ...)

but if I call the type Attribute_Name I'll have problems naming variables of 
that type (because Attribute_Name seems to be the best name for them as 
well). 

That's one of the things I dislike in Ada - everything (types, variables, 
packages, operations) follows exactly the same naming convention and doesn't 
use any special character/whatever to distinguish between them, so you run 
out of good names in no time...

-- 
Marek Janukowicz

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[flat|nested] 13+ messages in thread

* naming, was Re: Design problem: generic package vs tagged subtype
  2010-06-30 22:33   ` Marek Janukowicz
@ 2010-07-01  4:13     ` tmoran
  2010-07-01  9:49       ` J-P. Rosen
  2010-07-01  5:57     ` Simon Wright
  1 sibling, 1 reply; 13+ messages in thread
From: tmoran @ 2010-07-01  4:13 UTC (permalink / raw)


> That's one of the things I dislike in Ada - everything (types, variables,
> packages, operations) follows exactly the same naming convention and doesn't
> use any special character/whatever to distinguish between them, so you run
> out of good names in no time...
    You are welcome to invent your own prefixes or suffixes.  Words in
English often don't use those but depend on context and syntax to
disambiguate.  The fish in the bowl was one of the fish in the stream, but
I decided to go fish in the stream and tell this fish story.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-06-30 22:33   ` Marek Janukowicz
  2010-07-01  4:13     ` naming, was " tmoran
@ 2010-07-01  5:57     ` Simon Wright
  2010-07-01 18:30       ` Jeffrey R. Carter
  1 sibling, 1 reply; 13+ messages in thread
From: Simon Wright @ 2010-07-01  5:57 UTC (permalink / raw)


Marek Janukowicz <marek@janukowicz.net> writes:

> Simon Wright wrote:

>                                                         I'm a bit lost in 
> this subject in general: could anyone tell me the exact difference between:
> - array (Attribute_Type)
This is an array indexed by the full range of the index type.

> - array (Attribute_Type range <>)
This is an array indexed by some contiguous subset of the full index
type.
If Attribute_Type was (A, B, C) any particular array could have no
elements or elements (A), (B), (C), (A, B), (B, C), (A, B, C) .. but not
elements (A, C).

> - array (Attribute_Type'Range)
This isn't allowed in a generic formal part.

>> As a side note I really dislike the name Attribute_Type_Type. It seems
>> to me that what you've called Attribute_Type is much more like a Name
>> than a Type.
>
> Yeah, you might be right on that. I still need to find out what a good 
> naming convention would be. I wouldn't like to use:
>
> type Attribute_Name_Type is (Id, Username, ...)
>
> but if I call the type Attribute_Name I'll have problems naming variables of 
> that type (because Attribute_Name seems to be the best name for them as 
> well).

Maybe inserting another concept would help? Tables <have Columns which>
have Attributes. If you have table names, why not column names? Could
Column or perhaps Component be described by a record structure
(name, kind, ...)?

> That's one of the things I dislike in Ada - everything (types, variables, 
> packages, operations) follows exactly the same naming convention and doesn't 
> use any special character/whatever to distinguish between them, so you run 
> out of good names in no time...

Kind and Sort can help, though (a) a bit English, maybe, (b) you'd still
need some convention about which is the more abstract.

Grady Booch used to use The_<type_name> for variables, which can get
rather ugly.

Use context -- I'd much rather write
  procedure Send (M : Message);
than
  procedure Send (The_Message : Message);
or, much worse,
  procedure Send (Message_To_Send : Message);



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: naming, was Re: Design problem: generic package vs tagged subtype
  2010-07-01  4:13     ` naming, was " tmoran
@ 2010-07-01  9:49       ` J-P. Rosen
  2010-07-01 15:48         ` Marcelo Coraça de Freitas
  0 siblings, 1 reply; 13+ messages in thread
From: J-P. Rosen @ 2010-07-01  9:49 UTC (permalink / raw)


tmoran@acm.org a �crit :
>> That's one of the things I dislike in Ada - everything (types, variables,
>> packages, operations) follows exactly the same naming convention and doesn't
>> use any special character/whatever to distinguish between them, so you run
>> out of good names in no time...
>     You are welcome to invent your own prefixes or suffixes.  
... and have your naming rules checked by AdaControl (sorry, couldn't
resist) ;-)


-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: naming, was Re: Design problem: generic package vs tagged subtype
  2010-07-01  9:49       ` J-P. Rosen
@ 2010-07-01 15:48         ` Marcelo Coraça de Freitas
  0 siblings, 0 replies; 13+ messages in thread
From: Marcelo Coraça de Freitas @ 2010-07-01 15:48 UTC (permalink / raw)


First I'd like to say I am sorry if my text writing isn't quite clear.
I am not a native english speaker and I haven't spoken in this
language for quite a while now.


I have come through some of those problems when I was design KOW_Ent
(another Ada ORM, which is MGPL and is based on APQ-Provider which is
a database connection pool implemented using APQ).


I decided to use tagged types all over the place (the only generic
package was for building queries and returning vectors of objects,
which is being replaced by a non-generic implenentation... well, I am
getting off topic now.. hehe).


Each persistent type extends KOW_Ent.Entity_Type (which already has an
ID, a field for storing filtering tags (in the web sence) and the
original entity tag (it is possible to extend a type further).

The columns are represented by the KOW_Ent.Entity_Property_Type. Each
data type is represented by it's very own Entity_Property_Type
implementation which holds access to a function to get the data from
the object and a procedure that sets it.

For the engine to work it is needed to register the entity type and
it's properties:


An example of code generated by a tool created to easy the development
of kow_ent based applications is:

                KOW_Ent.Entity_Registry.Register(
                                Entity_Tag      =>
teca.Entities.Content_Entity'Tag,
                                Table_Name      => "teca_contents",
                                Id_Generator    => null,
                                Factory         =>
The_Content_Entity_Factory'Access
                        );


                KOW_Ent.Entity_Registry.Add_Property(
                        Entity_Tag      =>
teca.entities.Content_Entity'Tag,
                        Property        =>
KOW_Ent.Properties.New_UString_Property(
 
Column_Name     => "title",
 
Getter          =>
teca.Entities.Content_Entity_title_hlp.getter'Access,
 
Setter          =>
teca.Entities.Content_Entity_title_hlp.setter'Access
                                                                ,Length
=> 255
                                                )
                      );

By the way, the factory is used by the web interface for handling
database data which is part of the KOW_View-Entities module.

The data loading process is done by the KOW_Ent.Load procedure:
        procedure Load( Entity : in out Entity_Type'Class; ID : in
ID_Type );

It then queries the registry and load the data - that will come from
different tables when you extend another existing entity type. The
store procedure works basically the same.


I hope my 50 cents can help you in your task.


Regards,
--
Marcelo C. de Freitas
http://framework.kow.com.br



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-01  5:57     ` Simon Wright
@ 2010-07-01 18:30       ` Jeffrey R. Carter
  2010-07-01 19:28         ` Simon Wright
  2010-07-02  9:25         ` Stephen Leake
  0 siblings, 2 replies; 13+ messages in thread
From: Jeffrey R. Carter @ 2010-07-01 18:30 UTC (permalink / raw)


On 06/30/2010 10:57 PM, Simon Wright wrote:
>
> Use context -- I'd much rather write
>    procedure Send (M : Message);
> than
>    procedure Send (The_Message : Message);
> or, much worse,
>    procedure Send (Message_To_Send : Message);

I don't really care which of these I write. But I'd much rather READ

Send (Message => ...);

than

Send (M => ...); -- Meaningless

or

Send (The_Message => ...); -- Prefixes decrease readability

or

Send (Message_To_Send => ...); -- "much worse"

so I'd probably write

procedure Send (Message : in Message_Info);

or something like that. More importantly, I'd decide that I want to read 
"Message" as the formal parameter name 1st, and from there decide on my type name.

I understand that this requires thinking before coding, and so will never be 
popular.

-- 
Jeff Carter
"My dear Mrs. Hemoglobin, when I first saw you, I
was so enamored with your beauty I ran to the basket,
jumped in, went down to the city, and bought myself a
wedding outfit."
Never Give a Sucker an Even Break
111



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-01 18:30       ` Jeffrey R. Carter
@ 2010-07-01 19:28         ` Simon Wright
  2010-07-01 19:59           ` Jeffrey R. Carter
  2010-07-02  9:25         ` Stephen Leake
  1 sibling, 1 reply; 13+ messages in thread
From: Simon Wright @ 2010-07-01 19:28 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> writes:

> I don't really care which of these I write. But I'd much rather READ
>
> Send (Message => ...);
>
> than
>
> Send (M => ...); -- Meaningless

Quite often (IMO) there's no need to use named association *for the
first parameter* in a case like this.

   Send ("hello world", To => Server);

for example.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-01 19:28         ` Simon Wright
@ 2010-07-01 19:59           ` Jeffrey R. Carter
  2010-07-01 21:14             ` Per Sandberg
  0 siblings, 1 reply; 13+ messages in thread
From: Jeffrey R. Carter @ 2010-07-01 19:59 UTC (permalink / raw)


On 07/01/2010 12:28 PM, Simon Wright wrote:
>
> Quite often (IMO) there's no need to use named association *for the
> first parameter* in a case like this.
>
>     Send ("hello world", To =>  Server);
>
> for example.

This violates my coding standard.

-- 
Jeff Carter
"Ada has made you lazy and careless. You can write programs in C that
are just as safe by the simple application of super-human diligence."
E. Robert Tisdale
72



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-01 19:59           ` Jeffrey R. Carter
@ 2010-07-01 21:14             ` Per Sandberg
  0 siblings, 0 replies; 13+ messages in thread
From: Per Sandberg @ 2010-07-01 21:14 UTC (permalink / raw)


Maybe,
But the sentence is readable for two legged carbon-based beings.
/P

On 07/01/2010 09:59 PM, Jeffrey R. Carter wrote:
> On 07/01/2010 12:28 PM, Simon Wright wrote:
>>
>> Quite often (IMO) there's no need to use named association *for the
>> first parameter* in a case like this.
>>
>> Send ("hello world", To => Server);
>>
>> for example.
>
> This violates my coding standard.
>



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-01 18:30       ` Jeffrey R. Carter
  2010-07-01 19:28         ` Simon Wright
@ 2010-07-02  9:25         ` Stephen Leake
  2010-07-02 10:50           ` Georg Bauhaus
  1 sibling, 1 reply; 13+ messages in thread
From: Stephen Leake @ 2010-07-02  9:25 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> writes:

> so I'd probably write
>
> procedure Send (Message : in Message_Info); 

Better yet:

procedure Send (Message : in <package_name>.Message); 

less thinking about names required.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Design problem: generic package vs tagged subtype
  2010-07-02  9:25         ` Stephen Leake
@ 2010-07-02 10:50           ` Georg Bauhaus
  0 siblings, 0 replies; 13+ messages in thread
From: Georg Bauhaus @ 2010-07-02 10:50 UTC (permalink / raw)


On 02.07.10 11:25, Stephen Leake wrote:
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> writes:
> 
>> so I'd probably write
>>
>> procedure Send (Message : in Message_Info); 
> 
> Better yet:
> 
> procedure Send (Message : in <package_name>.Message); 

Will this work well with AdaCore's <package_name>.Typ
convention, too?



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2010-07-02 10:50 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-30 17:52 Design problem: generic package vs tagged subtype Marek Janukowicz
2010-06-30 19:23 ` Simon Wright
2010-06-30 22:33   ` Marek Janukowicz
2010-07-01  4:13     ` naming, was " tmoran
2010-07-01  9:49       ` J-P. Rosen
2010-07-01 15:48         ` Marcelo Coraça de Freitas
2010-07-01  5:57     ` Simon Wright
2010-07-01 18:30       ` Jeffrey R. Carter
2010-07-01 19:28         ` Simon Wright
2010-07-01 19:59           ` Jeffrey R. Carter
2010-07-01 21:14             ` Per Sandberg
2010-07-02  9:25         ` Stephen Leake
2010-07-02 10:50           ` Georg Bauhaus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox