Piotras' blog: Archive
2006-01-01 - 2006-12-31
MidgardConfigFile
Posted on 2006-01-04 18:15:48 UTC.
Yeah, MidgardConfigFile is the new configuration directive for midgard-apache2 module. Takes only one argument. Filename.
Full path is defined by prefix used while midgard-core was compiled.
In my case I compiled midgard-core with prefix --prefix=/usr , so this file is located in /etc/midgard/conf.d directory.
This is smallest Midgard vhost configuration I have ever used:
Quite huge? ;)
ServerName ppmobile
DocumentRoot /var/lib/midgard/vhosts/ppmobile/8888
MidgardPageCacheDir /var/cache/midgard
MidgardConfigFile piotras
AddDefaultCharset utf-8
I am not going to explain midgard configuration file because it has every directive described and besides every directive is self explanatory.
Interesting thing is that I had to rewrite configuration file "handler" and make it fully OO.
Advantages:
- midgard-java or midgard-php bindings will be even easier to make.
- Internal functions like mgd_connect or midgard_get_database_connection may be methods of MidgardConnection object and take MidgardConfig object as parameter. Notice that data like username or password could be hidden even for midgard-core API!
- MidgardConfig object can be used as global runtime loghandler, Gerror handler, etc, etc.
- none
MidgardConfigFile automagically sets midgard-root file and Midgard engine.
Unfortunatelly this can not be done in midgard-apache1 module ( or I couldn't find DEFAULT_EXP_LIBEXECDIR for Apache1 ).
It's in the wall.
Posted on 2006-01-23 16:00:26 UTC.
It was almost 11 p.m. at friday when me and aga winded some burning. I started to knock every neighbour's door and ask if everything is ok. Yes, everything was ok.
Everywhere, except our place.
It's not ok when your home is full of smoke, right?
Few minutes after my phone call, firefighters were at our place. Four men was running up and down trying to locate fire's source. There was no doubt, the fire was already inside the building. They thought , the fire is inside the wooden floor.
One man asked another one to bring some axes and thermal sensitive camera. When he told me that they need to chop our floor I asked Aga
to put some warm clothes on and get only the most important things from our place. She decided to get only some papers and few DVDs with all pictures of our daughter taken since she was born.
"Luckily" one of the firefighters found fire's source. It was inside the wall.
In the flat at lower level...
I have never thought that one may use an axe so fast. And I have never thought that one may watch tv and be completely unaware that fire is so close.
Completely invisible.
Now all is fine , except the fact that our place is untouched , but completely useless because of huge stench. There is -20 ( -30 this night ) outside , so we can not ventilate our home...
midgard_reflection_property
Posted on 2006-01-26 11:33:06 UTC.
And here it is. Midgard goes reflected.
You should get latest CVS HEAD to try new midgard_reflection_property class.
MidgardSchema ( "oh my god , they killed MgdSchema" )
Posted on 2006-02-07 11:45:03 UTC.
It's going to be brief.
MgdSchema is no longer supported. Initial Midgard MgdSchema C structure is succesfully replaced with new object oriented MidgardSchema and MidgardSchemaClass.
A few benefits:
- Language bindings for schema initialization will be easy to write
- MgdObject and MgdObjectClass share the same data with MidgardSchema
- MidgardSchema data are global for midgard-core while private and invisible for midgard "extensions" like midgard-php.
- Memory management follows GObjects' rules
- Initialized Midgard Reflection is much easier to write and extend.
- Application's schema can be "extended" from xml standalone files ( private ones ) or directly from directories.
What really happens with Midgard
Posted on 2006-02-20 13:52:29 UTC.
I, Midgard Release Manager and Midgard core developer feel responsible
to share with my knowledge.
- Midgard produces SIGABRT because code is afraid when Chuck Norris is close.
- Chuck Norris is midcom-admin. Always
- Chuck Norris is invisible on #midgard channel. Always
- Chuck Norris never lefts #midgard. Never
- Midgard segfaults after Chuck Norris' roundhouse kick
- It wasn't typo , it was Chuck Norris.
- You are wrong if you think that Piotras can fix bug. Only Chuck Norris can do this.
- Chuck Norris never cries. He leaks
- Chuck Norris installed Midgard once. Perfect Software - he said.
- There's only MidNorr and ChuGard.
Łódź
Posted on 2006-03-01 12:04:27 UTC.
I just found
interesting news article about Łódź.
Well, it's not quite new, but it brings a bit of hope that Lodz
will be part of UE some day.
Lodz is the city I live in and where all latest midgard
releases are made.
Łódź in English means a boat , but this is very funny as
there is no river here ;)
You can even find 'boat ' in Midgard
releases' names.
There are also some nice galleries with pictures of Łódź.
Construct a better OO'ed day
Posted on 2006-03-01 12:13:11 UTC.
Day shouldn't be so frustrating when you can construct Your
midgard-php objects better , easier and faster.
I changed midgard-php objects' constructor a bit. Just follow
documentation.
Midgard 1.8alpha2 and PEAR
Posted on 2006-03-04 15:00:08 UTC.
I am trying to install
somehow Midgard
CVS
HEAD with pearized MidCOM.
At the beginning I was surprised that no pear packages is
installed , so I changed a bit my local
datagard script , to force it to exit before asking about
Virtual Hosts. As the initial setup is quite fast now I created
another one database so I was able to see what happens with
pear packages.
Installing PEAR packages...
downloading PEAR-1.4.7.tgz ...
Starting to download PEAR-1.4.7.tgz (280,249 bytes)
............done: 280,249 bytes
requires package `Archive_Tar' >= 1.3.1
PEAR: Dependencies failed
OK, that's not nice , but pear could handle this somehow.
And next line:
Command 'pear.midcom-project.org' is not valid, try 'pear help'
What? The command was:
pear channel-discover pear.midcom-project.org
Let's try help:
pear help channel-discover
Command 'channel-discover' is not valid, try 'pear help'
OK, let's try to look for it:
grep -re channel /usr/share/php/*
No results.
I am using debian and that means that I may have php4 and php5
installed , and if you consider the fact that pear script looks
for php command which is a link to php5 by default, you may
notice some not nice surprise with great segfault caused by
using php5 cli with midgard php extension builded for php4.
Currently I have no idea how to solve all these problems.
updated: I tested it
also with PEAR 1.4.6 , but with no luck
Midgard Reflection Property once again
Posted on 2006-03-27 14:33:27 UTC.
Why there's MidgardReflectionProperty when we had
MidgardObjectProperty?
Reflection used in class name better describes what this class
is designed for.
It's somehow usual now ( I know, one would say 'I do not
believe!' ) that we have reflection property class documented
already in
midgard-core and in
midgard-php documentation.
As always midgard-php part of reflection property was the worst
part.
I needed to change this :
$mrp = new midgard_reflection_property();
echo $mrp->description("midgard_article", "sitegroup"));
to:
$mrp = new midgard_reflection_property("midgard_article");
echo $mrp->description("sitegroup"));
A well known "big deal" is a possibility to fetch GObject
instance while using php object. At first I decided to use
Zend's resources ( sorry , I do not provide any url to zend
sites ). But the problem with Zend resources is the fact that
resources' id (very internal feature IMO) is available on zend
and php level. As there is no possibility to set own private
pointer as a member of zend object , one is forced to add
resource's id as object's property.
Now think about 200 php object instances and 200 integers, it's
easy to change object's resource's property value from 199 to
10 ( for example ) and get something very unexpected.
And now think about objects which use some ACL features in
"critical mission" environment and possibility to change any
resource id...
Let me quote:
"Watch, but do not touch. Touch, but do not taste".
I think this sentence from "The Devil's Advocate"
describes perfectly the sense of resource handlers.
I spent some time on reading php-gtk sources. (It's a good way
to "kill" your time anyway when you work with Zend. Read plenty
of source code and try to understand it.) I thought that I
could find some good way to make a good wrapper and use 1:1,
php and gobject objects.
No way. This extension uses 0 property as resources handler for
gtk object. What happens if I change value 1 ( let's say some
window object ) to 2 ( let's say some other widget object)? I
expect bad things.
At the end I decided to write very easy objects "collection". A
collection which holds 1:1 references for zend ( php in this
case ) and gobject objects. The idea is very simple. I use two
data types: GHashTable and GSList.
The first one is a collection of zend objects' pointers
assigned as hash keys , and gobject ones assigned as values. If
HashTable is initialized with NULL compare functions then
direct equal ( pointers ) one is used.
The second one is used as collection of pointers to any gobject
which was initialized during particular request. So at the end
of the request , it's enough to iterate over list and free all
objects memory. Plain and simple.
The only problem I can see is zend object pointer which can be
"overwritten" during some loop. What really happens with this
pointer then? If You know, or you just found zend docs about
this, feel free to tell me ;)
Before Midgard 1.8 is out.
Posted on 2006-04-01 14:01:29 UTC.
Yes, I know. It's April the 1st. But I am deadly serious.
What is the most important for 1.8 release:
- stability
- performance optimization
- feature enchancements
It's quite hard to write about all changes in some particular
order.
MgdSchema and its
"self defense" possibility.
Improved
Midgard Query Builder and possibility to add
complex constraints and
orders.
Improved
datetime types support for object properties and
midgard_metadata class.
Derived
class support for Midgard Query Builder on midgard-php
level.
Recently, I updated
mgd_auth_midgard function docs. The "old" docs described
boolean value returned , while in practice person's id is
returned. Such "small" detail...
And last but not least.
Upcoming 1.8 release is fully
backward compatible.
midgard-php Apache free
Posted on 2006-04-30 18:02:01 UTC.
It's going to be short.
But one would elaborate a bit about such issue, though :)
Midgard 1.8alpha2
is going to be released soon, and this is going to be the first
Midgard release with midgard-php module absolutely Apache
unaware.
Midgard-php is a pure php
module.
On debian, you may use the same midgard module for Apache1 and
Apache2.
No need to recompile.
No need to configure this extension with plenty of arguments.
The only one need is a need to use Midgard ;)
Midgard on debian = more freedom
Posted on 2006-05-12 09:14:31 UTC.
I started to debianize latest Midgard 1.8alpha2
release and during all the changes I made I realized that
debian users should get more freedom and more flexibility while
using Midgard Framework
and Midgard CMS with this particular distro.
Debian policy doesn't allow to include symlinks like
`libmidgard.so` is library package. Package name must be
renamed following SONAME , so new midgard-core debian package
will be named libmidgard9. We can include only those so files
and ( symlinks ) which contain library version in name.
In theory ( you know how practice always looks like ;) I should
be able to update my production server to Midgard
1.8 using Apache1 server , and use Midgard
1.9 development release branch with Apache2 and PHP5 on the
same server without any need to break some setup.
In the other news. I
can not stand it any longer. lintian complains about missing
manual pages in debian packages for midgard , so I started to
write those.
I should commit manuals to CVS repository soon.
Midgard2 started here
Posted on 2006-05-19 14:40:10 UTC.
Ragnaroek starts here. It was two years ago.
Midgard2 started today.
Midgard-schema, command line tool uses Midgard2
API , including MidgardConnection handler object and
MidgardConfig object. In such shape it's going to be included
in upcoming Midgard
1.8 release.
To make life more easier I wrote first (initial) official
midgard-core docs.
Debian sid libc6 and Midgard with gcc4?
Posted on 2006-05-26 09:36:48 UTC.
Sunday. May 21st.
I run this sweet command on my Debian sid system.
apt-get dist-upgrade
blah blah blah
Replacing package libc6... Segmentation Fault...
First thing you can think about is mandatory ' WTF? ' .
dpkg segfaults, vi segfaults , cat segfaults , ls segfaults ,
everything segfaults ( well, at least other applications
segfault ;) . Force reboot... System doesn't run at all...
Second thing you can think about is second mandatory 'F***,
WTF?'.
In such case I could move hard disk to another machine and copy
system partition , but with notebook...? Thanks god, I created
additional empty partition when system, was installed for the
first time. Installed sid again , mounted home partition to
work with the same configuration and preferences and started to
install midgard. Obviously , sid provides gcc4 and only MySQL 5
server and client, so Midgard ( obviously again
) can not be much usefull. Can not , but could.
I was too lazy to reconfigure system to compile everything with
gcc3 , so I decided to fix this "should be resolved months ago"
issue, and luckily found few lines of code which should be
fixed.
The conclusion is simple. If the software you are working on
has fundamental issues, then you should think about dist
upgrade ( especially on debian sid ) , and with a bit of luck
you can get unstable useless system. Later, you can fix basic
issues.
I think , I should close this.
New cool Midgard features
Posted on 2006-06-14 17:08:09 UTC.
PAM authentication
Midgard is able
to
authenticate users with PAM module for years.
But sometimes you can not make it more flexible. Let's say you
use two or three virtual hosts for the same sitegroup. And to
make life more difficult every host should use
PAM module , but with different configuration. One should
authenticate via LDAP , another one via
Domain
Controller and another one via passwd file ( yeah , I know
last example is mad if you consider how Apache handles files
permissions ;).
With Midgard virtual hosts you could use MidgardAuthType
directive and set its parameter as "PAM". With new "soon to be
released" 1.7.6 release you will be able to define PAM service
name.
Service name is nothing more like filename located in pam
conf.d directory. Usually it is `/etc/pam.d`.
a. Create pam service file 'midgard_active_directory'
auth required /lib/security/pam_winbind.so
b. Configure vhost
MidgardAuthType PAM
MidgardPamFile midgard_active_directory
c. Restart Apache
Midgard Query Builder
With Midgard
CVS HEAD you can query objects and objects' parameters and
attachments. Paramaters and atachments are exceptions for Query
Builder. The same as
metadata is.
To add constraint for parameter use magic "parameter" word and
dot followed by property name.
$qb = new MidgardQueryBuilder('midgard_topic');
$qb->add_constraint('parameter.domain', '=', "midcom");
$qb->add_constraint('attachment.name', '=', "xml.gif");
$qb->add_constraint('metadata.created', '>', "20010101");
$qb->add_constraint('up', '>', 0);
$qb->execute();
Configuration File
New unified configuration file now can be located in system
/etc directory or just in user's home directory. Create config
file:
~/.midgard/conf.d/my_config
And load midgard application. Main configuration file will be
ignored in such case.
Collecting good conventions
Posted on 2006-07-07 12:10:31 UTC.
MidgardCollector
implementation is in progress. Briefly I can explain what
collector is ( or what should it be ) for those who do not know
it exactly.
MidgardObject methods gets all object's record and its data
from database unconditionally. It means that all you can do is
get particular record identified by some id or guid.
MidgardQueryBuilder is able to select objects' records from
database and use or developer is able to limit selected records
using constraints and thus can fully "interact" with 'WHERE'
part of the SQL query.
MidgardCollector is something much more flexible. User or
developer is able to limit 'WHERE' part of SQL query but
additionally is able to limit 'SELECT' part of the SQL query.
What is more important , selected data in collection can be
overwritten via
collector's API so the whole collection can be set
"manually" by human or by SQL query.
I knew that MidgardCollector implementation is going to be hard
, but I didn't thought that is going to be the most difficult
part of midgard-core since new MidgardSchema
technology has been
announced.
1. MidgardCollector
extends MidgardQueryBuilder. Well... easy to say if you
consider that first QB implementation is not GObject's
OO
and the whole QB internals is shared in 5~6 files without
public members, so trying to keep encapsulation of "class"
internals and sharing public data means: refactor me.
2. Make yourself
confused if you want to follow GObject's examples from manual
and code conventions used for GValues. There is important
difference between :
GValue value = {0, }; /* convention */
and
GValue *value = g_new0(GValue, 1);
The first one "initialization" end up with voodoo segfaults if
you try to manipulate "the pointers" here and there and
additionally provide them for PHP language bindings.
3. Make
midgard_collector class derived one for PHP language.
Especially when C structure of midgard-core is implemented as
MidgardQueryBuilder PHP class breaking convention which says
"do not use CamelCaps" for midgard classes. Well... I added
midgard_query_builder class for midgard-php and thus I can
easily follow midgard-core there and keep consistent logic for
class names.
4. Zend conventions
"rules". I wonder how
many zend developers made me a target for a shotgun if I have
never said anything good about zend.
a. Register internal
class for PHP using Zend.( Please guys! Never mix up php and
zend names! )
API provided by Zend developers requires hardcoded! class name passed as
argument because the API in this point uses sizeof instead of
strlen. So simply forget about dynamic class names pointers
used through this part of API.
b. I am awfull right
now , I know it:
There is no "Zend manual" part on php website. Instead you can
follow excellent link "Hacking the core of PHP". "Thank you!"
c. PHP5 ( language
based on Zend2 engine ) comes back to old convention to use
CamelCaps for function and methods name. I know , one can use
CamelCaps with PHP4 , but this is nothing but php developers (
or maybe only pear ones ) convention , because Zend doesn't use
upper cases in names , forcing every single string to me
lowercased. Try to be so smart then and use black magic and get
class name or method name if what you can get is
MidgardQueryBuilder or MiDgArDqueryBuilDER. One may use
g_ascii_strdown all the time , but it's not the point to
remember about this. Especially when midgard community already
has been affected by such API change using PHP 4.x branch.
And hey! Last but not least! While beeing coach
potatoe , try to be a monkey for a few minutes when you can
follow monkey guys trip every
evening :)
Aha! I could forgot. Seems that deathmonkey race time has some
additionall 15 hours included.
midgard_language
Posted on 2006-07-24 16:54:06 UTC.
While discussion about midgard multilingual feature is in progress I added new midgard_language core's class.
Language class is defined as MgdSchema class so it's fully usable with Midgard Query Builder and sitegroup 0 admin can update languages or create new ones.
midgard_language has predefined 51 languages following ISO
639-1 language codes and names. If you want to update some
language use midgard_language.sql file located in
midgard/src/data/midgard CVS subdirectory.
Every language object has defined id property to use almost
deprecated now mgd_set_lang function which requires id as
argument. As soon as we release 1.8 stable , app's languages
will be settable via $_MIDGARD object ( not array ) with its
corresponding guid. I think guid is best choice as we can
switch to ISO 639-2 or 3 in a future.
For those who would like to test midgard_language:
$qb = new midgardquerybuilder("midgard_language");
$qb->add_constraint("code", "=", "en");
$ret = $qb->execute();
if($ret)
mgd_set_lang($ret[0]->id);
$article = new midgard_article($guid); $article->content = "Some only english text"; $article->update();
In other news:
midgard_collector is already implemented in midgard-core and
PHP bindings for midgard-php are ready as well.
Multilingual midgard_topic
Posted on 2006-07-24 20:44:05 UTC.
Just wrote about midgard_language. So , while beeing in
multilingual mood I updated midgard_topic so this class uses
mulitlang Midgard feature now.
Added new multilingual title property.
Moved extra and
description properties
to lang table.
Well... I just reminded myself how many work had to be done
with Midgard 1.4 to provide new feature , class definition and
SQL queries needed for them.
With almost new Midgard2, such changes are... trivial.
Thoughts are in the air :)
Posted on 2006-07-29 14:04:50 UTC.
Tigert just mentioned
about
Midgard for Gnome desktop.
Bergie mentioned about
GnomeGard
project many many many months ago.
And I , for last two weeks think almost about nothing but some
Gnome desktop application
which could be used as simple
Midgard Object's editor.
I am tired with editing css files via web browser. I am tired
with editing code via phpmole.
As plenty of code , especially style's one resides in Midgard
database , I can not use any simple text editor. WebDAV support
is far from being perfect and usable.
I just installed Glade with the
basic simple idea:
* Browse midgard classes
* Browse Midgard objects
* Use
midgard_reflection_property to define object's property
edit widget.
*
Connect with Midgard API ( no need to
configure Apache vhost for this )
To be shameless.
Midgard core API in current state , today, is ready for
Gnome desktop.
Even if such aplication is going to work in a year, I am going
to write it.
MOB mock-up
Posted on 2006-07-30 14:05:12 UTC.
As soon as I installed glade I created new project. Compiled
with midgard library and used few widgets. In this mock-up you
are able to select configuration name from the list. Connect to
Midgard database and see all MgdSchema classes in GtkTreeView
widget. And of course display about window :)
It's enough to install midgard-core and dev packages (
libmidgard9 and libmidgard9-dev in my case ) and use it with
glade. No hacks , no workarounds. Just easy as it should be.
Just yet another gtk application.
MOB - objects' tree
Posted on 2006-08-02 11:42:42 UTC.
Just few days ago I wrote that I am going to write midgard-gtk
object browser , even if I am to write it in a year. Today I
have registered class list and objects' tree browser. Limited
to root objects only, but I it will change within day or two.
A lesson from this part of MOB is that midgard misses some core
functionality ( mostly object's method ) which is able to
return only root objects if object's class is registered as
"content tree" one.
So to build object's tree we should have such three methods (
two of them are already implemented ):
- list_roots
- list
- list_childs
An interesting ( built in ) feature for tree widget is
search functionality.
If the tree has too many entries and you would like to find
particular one by name , it's enough if you start typing.
Exactly the same as you used to do using Firefox or Nautilus.
At this point I found one issue. Double clicking on
midgard_snippet just hangs application. Or at least it looks
like as I had no time to wait till it makes anything. Of course
I selected all
snippets. In such case it may be more than 5 thousands records.
Another interesting lesson from MOB writing is the fact that
core misses config file functionality which should return only
the names of configuration files or even better all the names of all
configurations. Such approach would encapsulate real file names
and could provide more readable configurations and their
"destinations" , like :
- midgard ( my.remote.host )
- midgard ( localhost )
- midgard ( my.another.host )
To be continued soon...
Aegir and PHP5
Posted on 2006-08-03 11:26:39 UTC.
If you try to run Aegir with PHP5 and you get this warning:
Parse error: syntax error, unexpected T_ABSTRACT, expecting ')'
in /var/cache/midgard/bergietest/1-5-5-0.php(991) : eval()'d code
(5) : eval()'d code on line 538
Edit /NemeinRCS/xml_rcs_functions snippet:
Line 538 is:
abstract => "CDATA",
Replace it with:
"abstract" => "CDATA",
MOB needs name
Posted on 2006-08-07 12:42:44 UTC.
This weekend I spent in bed. "Nice" two days with MOB's
code and heat. This is some kind of irony when temperature
outside is going down after very long and and very hot July and
my head's temperature is going up :)
MOB , Midgard Object Browser became a quite usefull
application. I was afraid that snippet's listing hangs mob so I
added
progressbar and now I know it's just takes too much time. I
didn't wanted to keep reading log files for successfull or
failed operations , so decided to keep track of any Midgard error in window's
statusbar.
Now , mob's features are:
- browse registered classes
- browse object's tree
- create new objects
- edit existing objects
- delete exisiting objects
I think it's high time to create Midgard subproject for mob,
but mob is not good name. Just let me know, if you think you
get good name for mob.
Magni
Posted on 2006-08-11 15:53:28 UTC.
MOB
has a new name. Magni.
And what is more important magni has new home.
I created Midgard's subproject on tigris with hope that this
kind of application one may find usefull.
It's not designed to be powerfull all in one application. I just
wanted to proof that midgard core became powerfull and it's
relatively easy to write midgard library dependant application.
First. Midgard core is not a CMS core, it's just database
abstracion layer with authentication mechanism and some built
in additional features. Thus , core is not your ideas aware.
That's good , because its generic purpose doesn't limit your
ideas. So together with other components ,( like midgard-apache
module or midgard-php ) it turns into powerfull CMS framework
which can be written in any language , like MidCOM
is written in PHP.
Second. Just imagine that your favourive PHP ( only PHP ) based
CMS which has been developed for last three years begins to be
interesting for java community. Imagine that CMS contains 50
000 lines of code. 20 000 is database releated code, another 20
000 creates logic and only 10 000 defines user interface. What
java community should do in such case? Write 50 000 lines of
java code and be in sync with PHP based development branch.
Sounds good? No.
Now imagine that you want to build Your new project with python
and Midgard as basement. It's enough then to write python
language bindings ( which is done only once ) and focus on Your
application. Amount of code which must be written depends on
project only. You do not have to worry about anything else.
As a good example, midgard-php bindings part for midgard_collector
type:
Execute method:
midgard-core C
MidgardCollector *object;
midgard_collector_execute(object);
/* SQL query is executed and you do not have to worry about it,
even if it's C */
PHP binding Zend ( 1 and 2 )
PHP_FUNCTION(_execute)
{
/* parse parameters and other Zend relaed stuff */
/* ... */
/* Get underlying GObject */
MidgardCollector *object =
(MidgardCollector *) php_midgard_fetch_object(getThis());
/* Invoke method */
midgard_collector_execute(object);
}
And finally
midgard-php:
$mc = new midgard_collector(mixed params);
$mc->execute();
The same you can do with java, pyhon, ruby or perl.
I skipped error handling in examples because it's not a point
here.
Third. How many database related webDAV services do you know?
5? 10? Maybe 1? With new midgard core it's possible to write
native Gnome
VFS module and share Midgard content as it could be mounted
cd-rom or floppy. How many Gnome or Nautilus plugins have you
seen written in PHP?
Another one thing is: if Your favourite CMS is written in PHP
and you need for example python small application for it, which
could be running on Nokia
770, you must read the second point of this blog. With new
midgard core you depend on language bindings only , it doesn't
matter if you need KDE or Gnome desktop app. You doesn't have
to know if you are going to use MySQL , MS SQL or PosgreSQL.
You do not have to know what SQL is. All you have to know is
the language you want to write Your app in.
And at the end , imagine this ( it's only theory , but I bet
you get the point ):
Your new website is online shop. And what you need is to know
when new item has been ordered via website. You do not have POP
mail account , so checking every single minute if order is
already there is just crazy and without any sense. So what you
exactly need is a tray small application which every minute
looks for new orders made via website ( exactly like POP mail
tray apps ).
Can you do this if Your powerfull CMS is written in PHP? No.
Can you do this with centralized written in C library (
database abstraction layer ) and decentralized applications?
Yes , you can.
And ah! Last but not least! How many code do you need to write
to create new classes and database "connectivity" for them
using PHP or Python? Plenty. How many code must be written with
Midgard? None.
Forgive me if that blog entry is too shameless. It's just true.
Exporting MgdSchema objects
Posted on 2006-08-28 11:36:09 UTC.
Midgard CVS HEAD supports nice and quite usefull export method
for MgdSchema objects. It is quite simple to export objects on
PHP level.
A code example for exporting whole sitegroup ( SG0 in this case
):
foreach ($_MIDGARD['schema']['types'] as $type => $val){
$replication_data_dir = "/some/path";
$qb = new midgard_query_builder($type);
$qb->add_constraint("guid", "<>", " ");
$ret = $qb->execute();
foreach ($ret as $object){
$filepath = $replication_data_dir."/".$type."_".$object->guid.".xml";
$dump_file = fopen($filepath, 'w');
$xml = $object->export();
if($xml) {
fwrite($dump_file, $xml);
fclose($dump_file);
} else {
echo mgd_errstr();
}
}
unset($object);
}
If you try to execute this code twice , you should get
MGD_ERR_OBJECT_EXPORTED errno returned for every export method
call.
Coming back from vacation
Posted on 2006-08-29 12:07:33 UTC.
Isn't that quite abnormal? I came back from vacation last
sunday and first thing I done yesterday was writting about
Midgard objects exporting ;)
So , we spent nice week travelling a bit through
Świętokrzyskie Mountains.
"A bit" means that on the back seat of your car is 4 years
old girl and never stops talking and always wants to go
just there where you do not plan to go :)
Few places of interest: Krzyżtopór
castle( who's from Sweden and destroyed it? ;), "Jurrasic
park"( this is interesting, Ola was very bored there "Are
we going to castle now?" ;), Paradise Cave (
unfortunatelly , no one is able to make pictures there ),
Piekoszewice
( castle among houses ).
And other interesting things: my daughter
is interested in new Apache Foundation logo, completely
new spider-admin , and even dead boar
is happy.
In other news: Today, I
will implement import functionality for Midgard objects, so
basic core based replication should be ready tomorrow.
Midgard2 replication preview
Posted on 2006-09-02 12:43:39 UTC.
Few days ago I wrote about
exporting objects from Midgard database. Now
it's time to import them to other database or even the same. I
can not elaborate about API method, cause it's simply and easy.
bool mgd_import_object(string xml_content);
or static method ( a bit unlogic if you want to
tie to particular class ):
midgard_classname::import(string xml_content);
or midgard-core's API:
gboolean
midgard_import_object(MidgardConnection *mgd, gchar *xml);
Usage is very simple , you just pass xml content
( as serialized object's data ) as function or method
parameter. Xml content is parsed in memory and particular
object instance is created. Then , import method starts to
figure out what's the best method which should be invoked:
Object's record identified by guid is not found:
- if it's already purged , do nothing
- if it's not found in repligard's table , create new record
Midgard API is used to create new record , so for example you
do not have to worry about duplicated name&up pairs.
Object's record is found:
- if imported object's revised datetime is less recent or the same as the same value of database object return with error number MGD_ERR_OBJECT_IMPORTED
- in other case , if imported object is marked as deleted , delete database object
- if both cases do not match update it
So , poor example could look like this:
$filename = "/path/to/midgard_article_b531b35cf54111daa870f9b1239adb8fdb8f.xml";
$filehandle = fopen($filename, "r");
$content = fread($filehandle, filesize($filename));
midgard_article::import($content);
/* or mgd_import_object($content); */
It's very initial real Midgard2 replication feature, but it
perfectly feets a future "big picture" ideas:
- Send me this document, report. I will reuse it's content as I need.
- Send me this news with attachment's , I will import it to my MidCOM's app and reuse with self defined parameters.
- Make fast backup of my objects
- Send me your last note to my jabber account ( if I am not available , it will be waiting for me)
- Export only approved documents.
- Import every single object I got with POST request data.
- etc etc etc
Past years proved that replication app is always far from being
perfect and what you really need is not always doable or is
very complex. I hope we're going to implement powerfull and
flexible replication feature ever was made for Midgard.
Generating docs with Doxygen
Posted on 2006-09-12 12:53:06 UTC.
Midgard-core documentation is generated with doxygen package.
Last sunday I experimented a bit with creating MidCOM
docs with it. I was wondering if doxygen is able to generate
PHP documentation while it's optimized for C, C++ and Java.
First. Doxygen package
includes nice wizard gui invoked with doxywizard
command. So when it's running you can simply define what you
really need.
- optimize for particular language
- create xml output , manual pages or even chm file
- create graphical diagrams for classes and relations
- create html ot latex
- create html in frames or not
- plenty more features
Second. It was big
surprise to see that basic documentation for MidCOM was created
in 6 minutes.
Third. It was huge
surprise to see that full documentaion with graphical diagrams
and source code references was created in 15 minutes.
An interesting thing is the fact that config file created by
doxywizard can be easily reused for documentation generated
from cron. So in such case all you have to worry about is
calling doxygen with specific doxywizard configuration files.
An issue which was clearly noticable was lack of midcom
application class. However midcom package has been included in
documentation. Probably it's some doxygen issue or simply the
fact that MidCOM docs has been created for PHPDoc , so the
syntax might be a bit different for both generators. Anyway ,
first impression was very nice. Doxygen created very nice html
pages with classes , variables, modules , diagrams, etc etc.
For me personally, for the first time MidCOM docs became
readable. Html pages created with PHPDoc seems to be very nice
as some IDE plugin with code completion support. Not for
reading anyway.
Midgard database indexes
Posted on 2006-09-22 14:00:39 UTC.
A week ago
Rambo wrote about MySQL optimization tricks. Today I
decided to make detailed tests with database performance.
Idea
I use
midgard_query_builder methods to produce SQL query, but the main
point is to test database itself so all queries are executed in
MySQL prompt as setting properties from MySQL resources is a
bottleneck here.
$qb = new midgardquerybuilder("midgard_topic");
$qb->add_constraint('up', '<>', 0);
$qb->add_constraint('parameter.domain', '<>', '');
$qb->add_constraint('parameter.name', '<>', '');
$qb->add_constraint('metadata.created', '>', '2002-02-01 00:00:00');
$qb->add_constraint('metadata.published', '>', '2002-02-01 00:00:00');
Query:
SELECT topic.guid, topic.sitegroup, topic.metadata_creator,
NULLIF(topic.metadata_created,'0000-00-00 00:00:00') AS
metadata_created, topic.metadata_revisor,
NULLIF(topic.metadata_revised,'0000-00-00 00:00:00') AS
metadata_revised, topic.metadata_revision,
topic.metadata_locker, NULLIF(topic.metadata_locked,'0000-00-00
00:00:00') AS metadata_locked, topic.metadata_approver,
NULLIF(topic.metadata_approved,'0000-00-00 00:00:00') AS
metadata_approved, topic.metadata_authors,
topic.metadata_owner,
NULLIF(topic.metadata_schedule_start,'0000-00-00 00:00:00') AS
metadata_schedule_start,
NULLIF(topic.metadata_schedule_end,'0000-00-00 00:00:00') AS
metadata_schedule_end, topic.metadata_hidden,
topic.metadata_nav_noentry, topic.metadata_size,
topic.metadata_published,
NULLIF(topic.metadata_exported,'0000-00-00 00:00:00') AS
metadata_exported, NULLIF(topic.metadata_imported,'0000-00-00
00:00:00') AS metadata_imported,topic.metadata_deleted,
topic.metadata_score, topic.up AS up,topic.id AS id,
NULLIF(topic.created,'0000-00-00 00:00:00') AS created,
topic.revisor AS revisor, topic.score AS score, topic.code AS
code, topic.creator AS creator,
NULLIF(topic.revised,'0000-00-00 00:00:00') AS revised,
topic.name AS name, topic.revision AS revision, topic.owner AS
owner, topic_i.title AS title, topic_i.lang AS lang,
topic_i.description AS description, topic_i.sid AS sid,
topic_i.extra AS extra FROM topic_i,topic,record_extension
WHERE (topic.up <> 0 AND record_extension.domain <>
'' AND record_extension.name <> '' AND
topic.metadata_created > '2002-02-01 00:00:00' AND
topic.metadata_published > '2002-02-01 00:00:00' AND
topic.name <> '') AND topic.id=topic_i.sid AND
topic_i.lang IN (0, 0) AND topic.guid =
record_extension.parent_guid AND topic.guid =
record_extension.parent_guid AND topic.sitegroup IN (0, 0) AND
topic.metadata_deleted = FALSE;
Note that we use SQL standardized NULLIF control flow function.
So on PHP level , never write code like :
if ( $object->metadata->created == '0000-00-00 00:00:00')
but instead write it simpler and faster:
if ( $object->metadata->created)
The test
MySQL Cache is off.
Query is executed 3 times every time when table is altered and
I use average time.
Indexes on id and sitegroup.
* 13 rows in set (18.96 sec)
CREATE INDEX deleted_idx ON topic (metadata_deleted);
* 13 rows in set (19.00 sec)
CREATE INDEX name_idx ON topic (name);
* 13 rows in set (19.04 sec)
CREATE INDEX up_idx ON topic (up);
* 13 rows in set (19.06 sec)
CREATE INDEX metadata_created_idx ON topic (metadata_created);
* 13 rows in set (19.05 sec)
CREATE INDEX metadata_published_idx ON topic
(metadata_published);
* 13 rows in set (19.12 sec)
CREATE INDEX record_extension_oid_idx ON record_extension
(oid);
* 13 rows in set (19.04 sec)
CREATE INDEX record_extension_domain_idx on record_extension
(domain(255));
* 13 rows in set (19.04 sec)
CREATE INDEX value_idx ON record_extension (value(255));
* 13 rows in set (19.05 sec)
CREATE INDEX name_idx ON record_extension (name(255));
* 13 rows in set (19.02 sec)
CREATE INDEX parent_guid_idx ON record_extension
(parent_guid(80));
* 13 rows in set (0.01 sec)
(!!)
CREATE INDEX tablename_idx ON record_extension
(tablename(255));
* 13 rows in set (0.01 sec)
All indexes dropped ( except id and sitegroup ).
* 13 rows in set (19.25 sec)
Similiar query , but without parameters.
$qb = new midgardquerybuilder("midgard_topic");
$qb->add_constraint('up', '<>', 0);
$qb->add_constraint('metadata.created', '>', '2002-02-01 00:00:00');
$qb->add_constraint('metadata.published', '>', '2002-02-01 00:00:00');
I executed this query with and without metadata indexes. The difference between queries time was none.
Conclusion
Indexes for referenced properties ( on object level and
"foreign keys" on database level ) are the keys for
performance. And indexes used for queries when the same table
is used seem to not increase performance at all.
However this can be different for queries which join the same
table.
midgard-project.org update
Posted on 2006-10-06 19:01:07 UTC.
Today I updated Midgard setup on the host which serves www.midgard-project.org
website. Unfortunatelly I couldn't use datagard as remotes
database server doesn't allow login in as database
administrator, so update has been made step by step manually.
A good news is the fact that debian packages was used to update
Midgard environment.
If you need to
update remote database and can not use datagard , try this
script:
Database update
#! /bin/sh
. /usr/share/midgard/datagard/datagard.conf
# Set default initial values
_DATABASE_NAME="midgard"
_DATABASE_HOST="127.0.0.1"
_MGD_DB_USER="midgard"
_MGD_DB_PASS="midgard"
_SG_USER="admin"
_SG_PASS="password"
mgd_set_config_data MGD_DB_ACTION Update
mgd_set_config_data MYSQL_ADMIN_USER root
mgd_set_config_data MYSQL_ADMIN_PASS ""
mgd_set_config_data MGD_DB_HOST $_DATABASE_HOST
mgd_set_config_data MGD_DB_USER_NAME $_MGD_DB_USER
mgd_set_config_data MGD_DB_USER_PASS $_MGD_DB_PASS
mgd_set_config_data MGD_DB_NAME $_DATABASE_NAME
mgd_set_config_data MGD_SG_USER_NAME $_SG_USER
mgd_set_config_data MGD_SG_USER_PASS $_SG_PASS
mgd_set_config_data MGD_UPDATE_DB $_DATABASE_NAME
mgd_set_config_data MGD_DB_CONNECT_HOST $_DATABASE_HOST
mysqlcmd="mysql --host=$_DATABASE_HOST --user=$_MGD_DB_USER --password=$_MGD_DB_PASS"
mgd_update_db
mgd_update_db_for_utf
This is of course
example , and you might want to tweak it for particular
needs.
A few nice features I discovered (oops , I wrote
it :) after updating midgard:
- All SQL errors are reported to apache error log file whithout any need to change apache log level and without any need to reboot. Took me long while to find apache main error log , but at last I was nicely surprised.
- Schema validation is much much more better than this one wich exists in 1.7 branch.
Starting apache 1.3 web server...midgard-core (pid:30299):(WARNING): Wrong node name 'propetty' in '/usr/share/midgard/schema/org_openpsa_core.xml' on line 137
B&W
Posted on 2006-10-10 22:28:18 UTC.
It's not actually Black and White. It's almost black with some
minimal amount of white ( or grey ).
Anyway , I like it :)
Does anyone from Midgard community has something with colours?
Set of scripts
Posted on 2006-10-18 16:48:22 UTC.
While googling yestarday, I found few old entries about
Midgard on Polish
mailing lists. A few of them:
- Midgard is only set of scripts
- Midgard is distributed only as selected distros' binaries
Isn't it funny? :)
I am looking forward for multilanged MidCOM
so I think some Midgard documentation or concpets could be
easily translated to Polish then.
Another interesting thing is the fact that I almost finished
new parameter method for Midgard objects.
A new one is ( tries to be ) much clever then legacy one and
uses parameters' cache based on
midgard_collector.
Simply it means that first call for some parameter in some
domain , forces core to cache all domain parameters, so later
call to the same parameter or another one in the same domain is
"as slow as" :
$value = $arry['key']
No database selects.
This implementation will be introduced in Midgard since 1.8.1.
And something for high-tech fans: Midgard 1.9 is going to be released
soon!
Midgard 1.9 work just started
Posted on 2006-10-24 19:23:45 UTC.
Bergie just mentioned about
Midgard 1.8 and first cleanup commit.
As a result of today's work we have partially legacy free and
compilable Midgard framework. Partially means that I am not so
crazy to remove everything at once, as 1.9 release might use
some legacy code or solutions to provide smooth CVS and alpha
releases installations.
There is no repligard, no Aegir, no Spider. No legacy API in
midgard-php extension. No Apache1 module.
Next few days I will implement ligbda support , so 1.9.0alpha1
release is almost here.
I realized today, how much work is still left to get fully
Midgard2...
And quoting
Arttu:
Midgard is an IT project so
we can expect delays. Seven years sounds rather long, but Rome
wasn't built in a day and conquerring the world is even more
difficult.
During last two years we made almost 20 releases.
And we brought Midgard to desktop. We just made very unique and
powerfull CMS/Framework system. We even can not compare Midgard
with other CMS'es. Simply , they can not be used in Apache and
desktop environment.
Maybe Midgard2 is postponed
seven years. But last two years really count!
Midgard 1.8 - PEAR issues on debian stable
Posted on 2006-10-27 12:21:18 UTC.
There is an issue with PEAR on debian stable. So Installing
Midgard 1.8 is a bit difficult. As a workaround I found this
solution a good start to install all PEAR packages.
# Upgrade PEAR on debian stable
pear upgrade Archive_Tar
pear upgrade pear-1.3.3 && pear upgrade pear
# Discover channels
pear channel-discover pear.midcom-project.org
pear channel-discover pearified.com
pear install pearified/Role_Web pear install midcom/Role_Mgdschema #Debian related stuff pear config-set mgdschema_dir /usr/share/midgard/schema pear install midcom/Role_Midgardsql pear config-set midgardsql_dir /usr/share/midgard/sql/update pear install midcom/Role_Midgardelement # By default this is midgard, but you might want to change it pear config-set midgard_config_file /etc/midgard/conf.d/midgard # Install packages pear install pearified/JavaScript_Prototype
pear install Mail_Mime
pear install midcom/midcom_helper_datamanager2
pear install -f midcom/org_openpsa_httplib
pear install -f midcom/net_nemein_calendar
pear install -f midcom/midcom_helper_imagepopup
pear install -f midcom/midcom_helper_search
pear install -f midcom/de_linkm_sitemap
pear install -f midcom/midgard_admin_sitewizard
pear install -f midcom/net_nehmer_static
pear install -f midcom/fi_protie_navigation
pear install -f midcom/Javascript_protoToolkit
pear install -f midcom/midcom_helper_datamanager
pear install -f midcom/midcom_admin_content
pear install -f midcom/no_bergfald_rcs
pear install -f midcom/org_routamc_photostream
pear install -f midcom/org_routamc_gallery
pear install midcom/net_nehmer_blog
After running all these commands I suggest to re run datagard
and select PEAR again from menu. Sitewizard will be set
correctly then , even if PEAR packages will fail to install
from datagard menu.
Updated: I removed pear install -f midcom/net.siriux.photos
Updated:
- Removed pear install -f midcom/midcom_helper_toolbar
- Added debian related instructions
Updated (16.11.2006):
Discover channels before installing packages.
( Excellent point from Sentrum2 , #midgard :)
Midgard and PostgreSQL, first issues
Posted on 2006-10-28 20:56:18 UTC.
Just had to copy it here. Instead of screenshot.
This is well know play. Find three words which doesn't exist in
Midgard documentation.
Schema (pid:7822):(m): Type
midgard_language
midgard-core
(pid:7822):(WARNING): Midgard connection error: ERROR: syntax
error at or near "SET" at character 30, No:(-1),
src:gda-postgres
SQL: Not available
midgard-core
(pid:7822):(debug): query = INSERT INTO midgard_language SET
locale='', code='', description='',
name='_schema_test_create-1392903333', native='',
guid='64f93ec466ab11dba55db529ad5a9fa89fa8',sitegroup=0,metadata_creator='',
metadata_created='2006-10-28 17:40:25+0000',
metadata_revised='2006-10-28 17:40:25+0000',
metadata_revision=0, metadata_revisor='', metadata_size=115
,metadata_locker='' ,metadata_locked='' ,metadata_approver=''
,metadata_approved='' ,metadata_authors='' ,metadata_owner=''
,metadata_schedule_start='' ,metadata_schedule_end=''
,metadata_hidden=0 ,metadata_nav_noentry=0
,metadata_published='2006-10-28 17:40:25+0000'
** (MIDGARD:7822): CRITICAL
**: gda_postgres_provider_get_last_insert_id: assertion
`GDA_IS_POSTGRES_RECORDSET (recset)' failed
Why Plone needs Midgard
Posted on 2006-11-01 00:32:19 UTC.
Recently , I followed these threads:
I wonder how Zope and Plone can be extended?
Can I use Java with Plone?
Can I use PHP with Plone?
Can I use pure GTK+ with Plone?
Can I use SQLite or PostgreSQL or MySQL with Plone?
I wonder about such sentence:
If you can see the beauty,
then Python got you
And I wonder about comprehensive and standardized tools which
can be reused in any environment.
Zope and Plone developers, Midgard uses GLib
and GObjects
as its base. If you need to extend Zope , just use Python
language bindings for Midgard. It's easy.
I can of course implement PHP bindings for Plone.
ZEND2 - Developer's hell
Posted on 2006-11-27 13:35:48 UTC.
Recently I had to fix few important issues related to Zend2
engine and
midgard-php extension. All issues were relatively easy to
fix , but I realized that hell is coming.
some_class::static_method();
Such language construction works fine with PHP4 and with PHP5.
The difference is that with Zend2 ( PHP5 ) 'static_method' must be explicitly
defined as zend static method and not as function ( PHP4 ).
Not a big deal, but ZEND_METHOD macro is expecting class name
for which static method is implemented. And this simply can not
be passed to macro as variable and must be hardcoded. Well, I
could be a writer if I would like to write , write and write. I
must reserve endless hours to implement midgard-php extension
as pure PHP5 one. Hacks, trials and errors, segfaults, hacks,
trial end errors... looping. I didn't read Zend2 sources yet
and have no idea how ZEND_METHOD is implemented but I expect
Zend guys still use sizeof instead of strlen in such macros so
what absolutely must be done is to forget about Zend2 API and
write own solution when you work with unknown variables.
Another interesting issue is the fact how GObjects ( or GTK )
ones can be implemented for PHP. For PHP5 I experimented with
direct pointers arrays, so there were no need to add some magic
__res property to PHP5 objects.
Unfortunatelly it fails on bigger loops like:
while(something) {
$var = new
some_class();
}
The solution is to only use __res property.
I wonder how it's safe if one can accidentally or explicitly
get "forbidden" object by changing object's __res property
value. This is a scripting language so fivth object instance
will always have __res value = 5. If this is some secret
account for example I can easily change my object's __res value
to 5 and get object which shouldn't be available for me.
And another interesting thing is memory usage and kind of
"optimization".
I almost finished basic midgard_replicator implementation.
And mandatory strings duplication makes me frustrated for
months. Why the hell I can not reuse string contents and I have
to duplicate it over and over?
Why string variable initialized without duplication parameter (
that's from docs ) triggers segfault when variable is destroyed
by zend?
I hope I am wrong. And if I am and some Zend developer is
reading it, please be so kind and give that magicall url where
such issues are very well documented.
Midgard-apache2. Refactoring.
Posted on 2006-12-28 12:53:06 UTC.
I
already blogged about libgda implemented in new midgard-core.
While it looks promising for command line applications it
started to be real problem in Apache2 environment. First of all I
began to refactor midgard-apache module with new GObject
based API.
As soon as I began I realized something really bad happened:
GLib-GObject-WARNING **:
cannot register existing type `midgard_connection'
The
midgard-core API call in this case could be simple limited
to two lines of code:
g_object_new(MIDGARD_TYPE_CONNECTION,
NULL);
gda_client_open_connection_from_string(client,
"MySQL", str, 0);
Why such two lines of code can trigger such warning? ( Keep in
mind that this "simple warning" was only a start of endless
critical errors reported and followed by segfaults ).
I started to check code, recompile midgard-core and
midgard-apache with different flags. But none of this things
seemed to help. I started to investigate libgda code and found
that the source of the problem is
GLib's GModule API. Well, rather Apache2 not being compiled
with gmodule flags.
One is able to easily reproduce it with such simple code:
g_object_new(GDA_TYPE_CONNECTION,
NULL);
g_module_open("/path/to/any/lib/module.so",
G_MODULE_BIND_LAZY);
I tried libgda and evolution's plugin in my case. It perfectly
breaks GType system.
OK, I decided to try this code not when midgard-apache module
is initialized but when http request is made. And it seemed it
worked. But not for a long time:
midgard-core
(pid:14649):(WARNING): Unable to create the configuration
file.
I/O error : Permission
denied
I/O error : Permission
denied
midgard-core
(pid:14649):(WARNING): Error saving config data to
/root/.libgda/config
It's not enough I am laying down, I must be kicked....
gda_client_open_connection_from_string in this case is a hack
and this function creates configuration file , reads data from
this file and when data ie read , file is cleaned. But it's not
trivial when Apache's child is not running with root
permission...
I started to write example codes to find any workaround
quickly, and finally I changed midgard_connection and
midgard_config code a bit, so some of API functions can easily
be invoked even if no object instance was created. Manipulating
with core's structures ( available as public API structures ) I
managaed to create database connection using libgda API ( when
module is initialized ) and create midgard_connection objects
when http request is made.
So far it looks very good. Especially midgard_connection object
looks good as its instance is created once and available as one
object per virtual server ( Midgard1 module uses one connection
structure per request). It looks like a very good start for
future caching possibilities.