Piotras' blog: Archive
2005-03-01 - 2005-03-31
mgd_get_me_by
Posted on 2005-03-02 12:09:37 UTC.
I was wondering about get methods for Midgard (MgdObject) and GObject objects. If we can define get_by_id by defining id property of an object we can simply define any get method following object's properties which are set. This means that after you define object's property up and name you can simply get object exactly as current mgd_get_by_name(up, name). When up and title are set you can call object as mgd_get_by_title(up, title). This method doesn't exists , but do we need to write another method?. This is very simply kind of find() method. The real problem is that you never know if you can get fetchable or single object. get_by_id method always returns object or NULL, which is much more simple from any point of view.
Current methods for MgdObjects, update() or create() work very similiar as simply find() method should work.
We get class' properties, check if property is defined and generate query. PHP ( or Zend ) object's methods works
the same way , we "map" all not MgdObject properties to MgdObject's ones.
So how do I do it using midgard-php extension?
<?phpor
$amerigard = new MidgardRocks();
$amerigard->get_by_id(1);
$amerigard->name = "Midgard is cool";
$amerigard->update();
?>
<?phpEasy?
$amerigard = new MidgardRocks();
$amerigard->name = "Midgard is cool";
$amerigard->create();
?>
Well, it looks easy if you look at this code. update() or create() methods do not take care about ownership, sitegroup or any other access control layer at this moment.
It is almost impossible to define midgard *mgd or MgdSchema per class. The idea of current MgdSchema is that one schema may be shared between applications or virtualhost. So one class' connection or "parent" schema may ( and will ) be different. Current solution is to define object's schema and midgard structure when object is initialized. So new MgdObject is created like this:
MgdObject *obj;
obj = midgard_object_new(midgard *mgd,
MgdSchema *schema,
gchar *name);
Bad thing is that for every object created we need to look for type in schema. But if You consider how fast is midgard core and how slow may be midgard-php application you can agree that one call or querry speed is not important. Important is how fast is getting all data required by application.
SQL querry speed is another issue. We can make one big "join" like querry to get full object when its storage is defined
in more than one table. This is not as fast as one querry to get data from one table. But if you get data from one table
per querry you need to define as many queries as many tables object uses as storage. This means that midgard-php object properties stored in record_extension table can not be retrieved with another API functions. Exactly the same API must be used for replicated or serialized objects. This means that this API should be MgdObject's API. I was also wondering about the same usage for object's attachments. Following parameter's idea you could define blob's mimetype as domain , its name as name and blobs itself as value. Think about "getting" one field from table according to another two ones which may be groupped as array for object's property, assigned as another object or just like parameters.
Another problem with single queries is class inheritance. If MidgardArticle extends MidgardRepligardClass , how querry should be build when all parent class' properties are child's one? If MyMidgard extends MidgardArticle , how should we know which property is from parent class? Search parent class for property?
Lets's look at our update method and its sql querry.
midgard-lib:1065:debug:query=UPDATE article SET up='0',locker='1',
approver='1',revisor='1',creator='1',type=136657063,locked='0000-00-00 00:00:00',
approved='0000-00-00 00:00:00',created='2003-04-28 05:56:46',revision=136656998,
revised='2003-04-30 09:46:00',score=136657126,name='index',extra3='',
extra2='',extra1='',print=136657020,view=136657009,icon=136657073,
caldays=136657114,calstart='1900-00-00',id=1,action='',
updated='',changed='',guid='',realm='' WHERE id=1 AND (sitegroup = 0 OR 0<>0)
midgard-lib:1065:debug:query failed: Unknown column 'action' in 'field list'
Action field is not defined in article table so querry failed. It doesn't matter I did not specify such property with such field in my schema. Property is inherited from parent class. So again. Create two queries and find which class property belongs to? While schema is created it generates parts of sql and store it in MgdSchemaType structure which is assigned to object when this is initialized as its private property. One does not need to waste expensive CPU time to create select querry during get method. The same may be done for create or update methods ( if "may" :).
GParamSpec may be usefull here, as MgdSchema creates "table.field" entries as nick values when define default class members. So MidgardArticle name property has "name" property and "article_i.name" nick. This should also define ACL attributes , as Midgard objects requires more than read and write flags. Property like sitegroup can not be "write" or "read". A special case is required as such property should be updated or created only for SG0 administrator, and with particular ACL API.
When we define flags per property we should be able to control not only object itself , but also every single property.
You can try to use MgdSchema objects with latest CVS tarballs.
Using midgard-php extension you should be able to:
- define class
- initialize object
- get object by id ( $object->get_by_id(int id) )
- create object ( $object->create() )
- update object ( $object->update() )
"Binary guys" responsible for binary packages of Midgard should start using latest CVS soon , as we slowly starting to prepare
1.7alpha release with changed core dependencies and midgard-data supporting fs midcom.
midgard-php ZTS ready
Posted on 2005-03-04 18:48:19 UTC.
No more no less.
While Debian maintainers enabled experimental ZTS feature in all PHP packages which are included in debian distribution , we had no other choice like tune midgard-php extension and make it ready for ZTS.
ZTS is Zend Thread Safety option , but requires php module to use ZTS macros which are absolutely safe while extension is compiled for PHP without ZTS.
Bad thing is that I can not recompile midgard packages for Debian.
We should have new midgard release next week instead. Which is absolutely good thing :)
Get midgard CVS to test ZTS and MgdSchema or wait till morning to get nightly tarballs.
midgard_object_find
Posted on 2005-03-15 15:20:12 UTC.
New midgard-core API function becomes a little usefull.
Library definition:
midgard_res *res;How it works on PHP level?
res = midgard_object_find(MgdObject mobj);
Quite trivial now , simple find() method.
$amerigard = NewMidgardArticle();This method returns fetchables with only id assigned as object property.
$amerigard->topic = $topic_id;
$amerigard->find();
Well, "only id" if you think about typical midgard php objects. There is also well known "N" , "__res__" and new property "errno".
print_r($amerigard);errno set to 0 is MGD_ERR_OK error string. Nothing New. The only difference: object itself handles such property.
NewMidgardArticle Object(
[name] => index
[N] => 6
[__res__] => Resource id #2
[errno] => 0
)
Let's get some more objects.
while ($amerigard->fetch())Hmmm.... It looks like mgd_list_topic_articles() ;)
{
$old_article = mgd_get_article($amerigard->id);
}
and
$amerigard = NewMidgardArticle();looks like mgd_get_article_by_name.
$amerigard->topic = $topic_id;
$amerigard->name = "index";
$amerigard->find();
Current limitation is sitegroup being defined according to host's sitegroup and one table usage. Which means there is no way
to get full object which is multilanged for example. But it is not future limitation :)
Ah! There is another funny "feature" with errno.
$amerigard = NewMidgardArticle();create() method doesn't return id which happens if You use mgd_xxx_create function. Instead of that object changes itself.
$amerigard->topic = $topic_id;
$amerigard->create();
So after calling create method object should have id set to id returned from mysql ( not 0 ) and errno set to 0 ( MGD_ERR_OK ). On failure object->id is set to 0 and errno is set to corresponding error number.
I wonder if this function could return full object and method like find_fast() fetchables ids.
Before April 1st starts
Posted on 2005-03-31 17:14:12 UTC.
I made few important changes in midgard-php extension , and in core header files. ( I still wonder why we have internal.h file , while it is used everywhere and simply all structures from this file could be in midgard.h file, which could make life a bit easier )
Midgard 1.7 release is going to be the first one since 1.4.x when we change dependencies for midgard-core. The most important change is that midgard depends on glib libraries >= 2.6 while we used glib 1.2.
Now, midgard may use ini like files to configure database, host , blobdir and all data which are still configured with Apache directives.
[Database]It is enough to call
#Database host ( 'localhost' by default )
Host=
# Name of the database
Name=
# Username for user who is able to connect to database
Username=
# Password for username
Password=
# etc etc
mgd_config_init("filename"); to initialize midgard in command line php. File passed as parameter to this function is searched in "/etc" directory which depends on prefix defined for midgard-core.In my case , directory config is /etc/midgard/conf.d ( --prefix=/usr ). There is no special convention to name files in conf directory. When you call mgd_config_init("amerigard") you want to initialize midgard from /etc/midgard/conf.d/amerigard file.
Unfortunatelly , all files ( especially with passwords ) stored under /etc directory should be readable only for root. And any user is not able to initialize midgard from command line. Now it means:
- initialize midgard only for installation purposes
- run as root and do not blame anyone when something wrong happens
A good point is that we could use the same configuration file for Apache vhost ( let's say MidgardConfig directive ), command line php , datagard, repligard, and more. If this is going to be a good way of midgard configuration , we should add another one ( only one ) config file where all default global variables are stored, like blobdir , or schemafile. At least, there is no need to specify blobdir , schema or even parser if one wants to follow defaults.
If I write about midgard-php I must write about two new methods ( for every object )
$object ->is_in_tree(int rootid, int id);Checks if object with id id is in object's tree with id rootid.
By default used for objects of the same type.
$object->is_in_parent_tree(int rootid, int id);Checks if object with id id is in parent object's tree with id rootid.
'Parent' doesn't mean parent object whcih is extended. It means parent in tree ( like article->topic ).
You can define parent and some tree data in schema.
<type name="NewMidgardArticle" table="article"There is no need to define which table is used by parent. It is defined in parent's iself definition.
parentfield="topic" parent="NewMidgardTopic'">
You can also wonder why we need two parameters for this function when we could use only one , root's one.
This is often ( I think ) when you check if object is in tree before you get it. In our case we just need to initialize
empty object , only to let midgard-core knows what table should be used.
And in other news
Adam Conrad ( php debian packages maintainer ) disabled ZTS in debian packages.It means that I need to rebuild midgard packages for debian and sing a song "catch me if you can" ;)