Index: openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml,v diff -u -N -r1.19 -r1.19.2.1 --- openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml 2 Mar 2004 19:02:15 -0000 1.19 +++ openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml 17 Apr 2004 14:11:03 -0000 1.19.2.1 @@ -613,6 +613,18 @@ + + Profile your code + There are several facilities for profiling your code in + OpenACS. The first thing to do is to install the + developer-support package and play around with it. But there + is also support in the API for profiling your code: + profiling + your code using ds_profile + + + Prepare the package for distribution. Browse to the package manager. Click on @@ -865,6 +877,116 @@ look at the forums package. + + Hierarchical data + + by Jade Rubick + with help from many people in the OpenACS community + + + One of the nice things about using the OpenACS object system + is that it has a built-in facility for tracking hierarchical data + in an efficient way. The algorithm behind this is called + tree_sortkey. + + Any time your tables are subclasses of the acs_objects + table, then you automatically get the ability to structure them + hierarchically. The way you do this is currently via the + context_id column of + acs_objects (Note that there is talk of adding in a + parent_id column instead, because + the use of context_id has been + ambiguous in the past). So when you want to build your hierarchy, + simply set the context_id values. Then, when you want to make + hierarchical queries, you can do them as follows: + + + db_multirow categories blog_categories " + SELECT + c.*, + o.context_id, + tree_level(o.tree_sortkey) + FROM + blog_categories c, + acs_objects o + WHERE + c.category_id = o.object_id + ORDER BY + o.tree_sortkey" + + + Note the use of the + tree_level() function, which + gives you the level, starting from 1, 2, 3... + + Here's an example, pulling all of the children for a given + parent: + + + SELECT + children.*, + tree_level(children.tree_sortkey) - + tree_level(parent.tree_sortkey) as level + FROM + some_table parent, + some_table children + WHERE + children.tree_sorktey between parent.tree_sortkey and tree_right(parent.tree_sortkey) + and parent.tree_sortkey <> children.tree_sortkey + and parent.key = :the_parent_key; + + + The reason we substract the parent's tree_level from the + child's tree_level is that the tree_levels are global, so if you + want the parent's tree_level to start with 0, you'll want the + subtraction in there. This is a reason you'll commonly see magic + numbers in tree_sortkey SQL queries, like + tree_level(children.tree_sortkey) - + 4. That is basically an incorrect way to do it, + and subtracting the parent's tree_level is the preferred method. + + This example does not include the parent. To return the entire subtree including the parent, leave out the non-equals clause: + + + SELECT + subtree.*, + tree_level(children.tree_sortkey) - + tree_level(parent.tree_sortkey) as level + FROM some_table parent, some_table subtree + WHERE + subtree.tree_sorktey between parent.tree_sortkey and tree_right(parent.tree_sortkey) + and parent.key = :the_parent_key; + + + If you are using the Content Repository, you get a similar + facility, but the parent_id + column is already there. Note you can do joins with + tree_sortkey: + + + SELECT + p.item_id, + repeat(:indent_pattern, (tree_level(p.tree_sortkey) - 5)* :indent_factor) as indent, + p.parent_id as folder_id, + p.project_name + FROM pm_projectsx p, cr_items i + WHERE p.project_id = i.live_revision + ORDER BY i.tree_sortkey + + + This rather long thread explains How + tree_sortkeys work and this paper describes + the technique for tree_sortkeys, although the OpenACS + implementation has a few differences in the + implementation, to make it work for many languages and the + LIKE construct in Postgres. + + + + Using .vuh files for pretty urls .Vuh files are special cases of .tcl files, used for rewriting incoming urls. We can use a vuh file to prettify the uri for our notes. Instead of note-edit?item_id=495, we can use note/495. To do this, we will need a new .vuh file for redirection and we will need to change the referring links in note-list. First, add the vuh: