Piotras' blog: Archive
2006-09-01 - 2006-09-30
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.