Archive - 2008

December 24th

Holiday in Taiwan

I am now having a Christmas holiday in Taiwan, from 23/12 to 31/12. Hopefully I will take some good photos :D


December 22nd

My personal battle before X'mas (Final part)

Saturday night to Sunday morning is another endless battle, almost all colorfully part are now complete. And it was 5am and so I need some sleep...:
DSC00100.JPGDSC00100.JPGDSC00101.JPGDSC00101.JPGDSC00102.JPGDSC00102.JPG

But once sleep for 5 hours, my brain feel refresh and keep focus again. The green parts are not simple because all looks similar, I need to keep on try-and-error (seems like debug programming...). Well, here are the complete product:

DSC00103.JPGDSC00103.JPG

Ok some more close up:

DSC00106.JPGDSC00106.JPGDSC00105.JPGDSC00105.JPGDSC00104.JPGDSC00104.JPG

Ok, so the main question is: where this puzzle goes for? For sure it is now delivered to my girl friend's home (not by DHL, I take it to her home manually...), and as her Christmas gift ;-)


My personal battle before X'mas (Part 2)

After one day, both Eeyore and Piglet are almost complete:
DSC00093.JPGDSC00093.JPG

Eeyore looks much smart now. Well, the mouth is not yet complete because the color too close to others. Look at the lovely sleepy Piglet, too. Part of flowers are also complete:

DSC00094.JPGDSC00094.JPGDSC00095.JPGDSC00095.JPGDSC00096.JPGDSC00096.JPG

For last Saturday I slept for few hours and start working again. Now Kessie is out there (hmm... is this Kessie? I am not sure, it just looks like some general Disney's characters). For Tigger I use a lot of time because of its pattern. Winnie the Pooh is not simple as its color may mixed with Tigger. Look at Eeyore, it mouth is now complete, too:

DSC00097.JPGDSC00097.JPGDSC00098.JPGDSC00098.JPGDSC00099.JPGDSC00099.JPG

December 19th

My personal battle before X'mas

Well... I haven't play puzzle for more than 5 years... Seems to be a punishment game... This is my target:
DSC00089.JPGDSC00089.JPG

After working for 3 hours, all edges are completed:
DSC00087.JPGDSC00087.JPG

Ok a close up to Eeyore (blue is the most simple...):
DSC00088.JPGDSC00088.JPG

Hopefully I can complete it before my Christmas holiday in Taiwan :D


December 17th

Adsense Injector 6.x-2.6-RC1 is out!

I have been using Drupal's Adsense Injector for more than years and love it so much: it is simple, elegant and just enough. But since my personal blog upgrade to Drupal 6.x, I get some trouble with it as there is no official release for Drupal 6.x. Well... I need to hack 5.x version for 6.x manually...

An upgrade patch is submitted 8 months ago which now obsoleted. Finkpad ask help from my blog directly, so Michael Curry and I start some join development for getting the work done.

If you are looking for this handy module as me, please feel free to download the latest 6.x-2.x development snapshot for testing and report bug if possible. With you kindly help stable release should be out soon :D


November 30th

Jesus is Sentenced to Death (Bible, Matthew: 27)

At every Passover Festival the Roman governor was in the habit of setting free any one prisoner the crowd asked for. At that time there was a well-known prisoner named Jesus Barabbas. So when the crowd gathered, Pilate asked them, "Which one do you want me to set free for you? Jesus Barabbas or Jesus called the Messiah?" He knew very well that the Jewish authorities had handed Jesus over to him because they were jealous.

While Pilate was sitting in the judgment hall, his wife sent him a message: "Have nothing to do with that innocent man, because in a dream last night I suffered much on account of him."

The chief priests and the elders persuaded the crowd to ask Pilate to set Barabbas free and have Jesus put to death. But Pilate asked the crowd, "Which one of these two do you want me to set free for you?"

"Barabbas!" they answered.

"What, then, shall I do with Jesus called the Messiah?" Pilate asked them.

"Crucify him!" They all answered.

But Pilate asked, "What crime has he committed?"

Then they started shouting at the top of their voices: "Crucify him!"

When Pilate saw that it was no use to go on, but that a riot might break out, he took some water, washed his hands in front of the crowd, and said, "I am not responsibility for the death of this man! This is your doing!"

The whole crowd answered, "Let the responsibility for his death fall on us and our children!"

Then Pilate set Barabbas free for them; and after he had Jesus whipped, he handed him over to be crucified.

(Bible, Matthew: 27)


November 28th

Drupal reserved word conflict with Oracle

accesslog.pathaccesslog.pathansi
accesslog.timestampaccesslog.timestampansi
accesslog.uidaccesslog.user_idoci
actions.typeactions.typewell-know
aggregator_item.timestampaggregator_item.timestampansi
authmap.moduleauthmap.moduleansi
authmap.uidauthmap.user_idoci
batch.timestampbatch.timestampansi
block.moduleblock.moduleansi
block_role.moduleblock_role.moduleansi
blogapi_files.uidblogapi_files.user_idoci
cache.datacache.dataansi
cache_block.datacache_block.dataansi
cache_filter.datacache_filter.dataansi
cache_form.datacache_form.dataansi
cache_menu.datacache_menu.dataansi
cache_page.datacache_page.dataansi
cache_registry.datacache_registry.dataansi
cache_update.datacache_update.dataansi
comments.commentcomments.bodyoci, well-know
comments.timestampcomments.timestampansi
comments.uidcomments.user_idoci
files.timestampfiles.timestampansi
files.uidfiles.user_idoci
filters.modulefilters.moduleansi
flood.timestampflood.timestampansi
history.timestamphistory.timestampansi
history.uidhistory.user_idoci
languages.domainlanguages.domainansi
languages.languagelanguages.languageansi
locales_target.languagelocales_target.languageansi
locales_target.translationlocales_target.translationansi
menu_links.depthmenu_links.depthansi
menu_links.externalmenu_links.externalansi
menu_links.modulemenu_links.moduleansi
menu_router.pathmenu_router.pathansi
menu_router.positionmenu_router.positionansi
menu_router.typemenu_router.typewell-know
node.commentnode.comment_modeoci, well-know
node.languagenode.languageansi
node.translatenode.translateansi
node.typenode.typewell-know
node.uidnode.user_idoci
node_counter.timestampnode_counter.timestampansi
node_revisions.timestampnode_revisions.timestampansi
node_revisions.uidnode_revisions.user_idoci
node_type.typenode_type.typewell-know
poll_votes.uidpoll_votes.user_idoci
profile_fields.typeprofile_fields.typewell-know
profile_values.uidprofile_values.user_idoci
profile_values.valueprofile_values.valueansi, well-know
registry.moduleregistry.moduleansi
registry.typeregistry.typewell-know
roleroleansi
search_dataset.datasearch_dataset.dataansi
search_dataset.reindexsearch_dataset.reindexsqlite
search_dataset.typesearch_dataset.typewell-know
search_index.typesearch_index.typewell-know
search_node_links.typesearch_node_links.typewell-know
search_total.countsearch_total.countansi
sessions.sessionsessions.session_dataansi, oci
sessions.timestampsessions.timestampansi
sessions.uidsessions.user_idoci
simpletest.filesimpletest.filenameoci
simpletest.functionsimpletest.functionansi
systemsystemansi
system.typesystem.typewell-know
url_alias.languageurl_alias.languageansi
users.accessusers.last_accessoci
users.datausers.dataansi
users.languageusers.languageansi
users.uidusers.user_idoci
users_roles.uidusers_roles.user_idoci
variable.valuevariable.valueansi, well-know
vocabulary.modulevocabulary.moduleansi
vocabulary_node_types.typevocabulary_node_types.typewell-know
watchdog.timestampwatchdog.timestampansi
watchdog.typewatchdog.typewell-know
watchdog.uidwatchdog.user_idoci

November 25th

Drupal 7.x Oracle driver development quick checklist

This is a quick checklist for develop Drupal 7.x Oracle driver. They need to be solved before Oracle slip into Drupal core.

Reserved word conflict (integrate with siren)

Drupal core use some reserved word of Oracle, e.g. uid. To solve this we have 2 choice: 1. escape all table/column/constrain name with escape characters (http://drupal.org/node/371#comment-636053), or 2. clone Moodle implementation and prevent the use of reserved words for all supported database (http://docs.moodle.org/en/XMLDB_reserved_words).

Here we choose to use solution 2. This come with some extra benefit that, if we need to connect Drupal's database from other projects, e.g. Moodle, they will able to fetch Drupal's column as there is no reserved word conflict. So this can improve both cross database and cross project compatibility.

Related issues:

VARCHAR2 is no large enough, use BLOB instead (integrate with siren)

This is another critical issue. Oracle only support VARCHAR2 with maximum 4000 characters. It is always not enough for CMS. As a replacement we can use BLOB because it is more universal.

We also need to clone PostgreSQL's BLOB handling for Oracle, with RETURNING.

Related issues:

Empty string is not allow in Oracle, and will translate as NULL (integrate with siren)

This is a critical bug of Oracle, all empty string will translate as NULL automatically. It is NO WAY for Oracle to emulate as other RDBMS because it is a 2-state machine (valid or NULL) but not 3-state (valid, empty or NULL). Logic Diagram:

|---------------------------------------------|
|         |     valid |     empty |      NULL |
|---------------------------------------------|
|  Oracle |   Support |        NA |   Support |
|---------------------------------------------|
| ANSI-92 |   Support |   Support |   Support |
|---------------------------------------------|

In order to overcome this limitation, we can first extend as 4 states: valid, "default", empty or NULL. Then restrict the use case as 3 states only, with replace the use of empty string as "default" value. Therefore both Oracle and other RDBMS can have identical support of SQL, and don't need to duel with different between = '' and IS NULL. Logic diagram:

|---------------------------------------------------------|
|         |     valid | "default" |     empty |      NULL |
|---------------------------------------------------------|
|  Oracle |   Support |   Support |        NA |   Support |
|---------------------------------------------------------|
| ANSI-92 |   Support |   Support |   Support |   Support |
|---------------------------------------------------------|

Procedure: 1. update all schema as nullable string if required (only allow null with valid default value but not empty string), 2. restrict all string I/O with no empty string (force translate as NULL), 3. debug and update programming logic for using empty string with "default" value if possible. Therefore:

  • Valid value: Keep untouch.
  • NULL: Act as default replacement of empty string if no programming logic break.
  • 'default': Use as exceptional replacement of empty string, work together with programming logic revamp.

P.S. This change will also benefit with the critical PostgrerSQL Blob bug with empty string (http://bugs.php.net/bug.php?id=41135), because we will no longer use empty string.

Related issues:

Auto upper case table and column name (integrate with siren)

This can be handle with PDO::ATTR_CASE (http://www.php.net/manual/en/pdo.setattribute.php). Becareful! Field names should be reserved word safe.

Related issues:

Max 30 characters for constraint name restriction (integrate with siren)

Oracle only allow 30 characters for constraint name. Moodle give a good example for solving this problem.

Related issues:

Some SQL functions need abstraction (integrate with siren)

Different database coming with different SQL syntax for same function, e.g. MySQL use SUBSTR, where PostgreSQL use SUBSTRING. Some simple abstraction is required. ADOdb give a good example for solving this problem.

Related issues:


November 15th

dev note: update text fields as nullable and no default

Prepare schema:

  1. Check target fields (http://edin.no-ip.com/node/166).
    a. No default + NOT NULL => can't accept NULL so valid value only (1 status only)
    b. Default with '' => remove
  2. Update schema with "NOT NULL => FALSE, (remove default)".
  3. Running update.php. Ensure schema is valid.
  4. Run related simpletest.

Once schema ready for expert install:

  1. ORACLE_NULL => NULL
  2. Before insert: check '' => NULL (!?)
  3. Before normal variable binding: '' => NULL
  4. check SQL syntax, change from = '' to IS NULL

Testing procedure:

  1. expert mode -> patch -> update
  2. normal mode -> patch -> update
  3. normal mode + all modules -> patch -> update
  4. patch -> install -> all modules


October 29th

Dummy code for makeConstraintName()

<?php
$table
= 'menu_links';
$fields = array('menu_name', 'plid', 'expanded', 'has_children');
$name = 'menu_plid_expand_child';

// Clone from PostgreSQL _createIndexSql() handling.
$result = Database::getActiveConnection()->prefixTables('{' . $table . '}_' . $name . '_idx');
var_dump($result);

// Handle with makeIndexName().
$result = Database::getActiveConnection()->makeIndexName($table, $fields);
var_dump($result);
?>