Index: openacs-4/packages/acs-core-docs/www/acs-admin.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/acs-admin.html,v diff -u -N -r1.43 -r1.43.2.1 --- openacs-4/packages/acs-core-docs/www/acs-admin.html 11 Dec 2010 23:36:31 -0000 1.43 +++ openacs-4/packages/acs-core-docs/www/acs-admin.html 12 Jun 2011 20:03:47 -0000 1.43.2.1 @@ -1,2 +1,2 @@ - -
Table of Contents
Table of Contents
Tutorials and reference material for creating new OpenACS packages. -
Table of Contents
Tutorials and reference material for creating new OpenACS packages. +
Table of Contents
Prev | Home | Next |
Appendix D. Using CVS with an OpenACS Site | Up | Chapter 14. Kernel Documentation |
Table of Contents
Download the Analog source tarball in
-/tmp
. Unpack, compile, and install analog.
[root aolserver]#cd /usr/local/src
-[root src]#tar xzf /tmp/analog-5.32.tar.gz
-[root src]#cd analog-5.32
-[root analog-5.32]#make
+ +Install Analog web file analyzer Download the Analog source tarball in +/tmp. Unpack, compile, and install analog.
[root aolserver]# cd /usr/local/src +[root src]# tar xzf /tmp/analog-5.32.tar.gz +[root src]# cd analog-5.32 +[root analog-5.32]# make cd src && make make[1]: Entering directory `/usr/local/src/analog-5.32/src' (many lines omitted) ***IMPORTANT: You must read the licence before using analog *** make[1]: Leaving directory `/usr/local/src/analog-5.32/src' -[root analog-5.32]#cd ..
-[root src]#mv analog-5.32 /usr/share/
+[root analog-5.32]# cd .. +[root src]# mv analog-5.32 /usr/share/ [root src]# cd /usr/local/src tar xzf /tmp/analog-5.32.tar.gz cd analog-5.32 make cd .. -mv analog-5.32 /usr/share/See also Set up Log Analysis Reports
View comments on this page at openacs.org +mv analog-5.32 /usr/share/
Analog is a program with processes webserver access logs, + +
Analog is a program with processes webserver access logs, performs DNS lookup, and outputs HTML reports. Analog should - already be + already be installed. A modified configuration file is included in - the OpenACS tarball.
[root src]#su - $OPENACS_SERVICE_NAME
-[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$cd /var/lib/aolserver/$OPENACS_SERVICE_NAME
-[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$mkdir www/log
-[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$cp -r /usr/share/analog-5.32/images www/log/
+ the OpenACS tarball.
[root src]# su - $OPENACS_SERVICE_NAME +[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ cd /var/lib/aolserver/$OPENACS_SERVICE_NAME +[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ mkdir www/log +[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ cp -r /usr/share/analog-5.32/images www/log/ [$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ su - $OPENACS_SERVICE_NAME cd /var/lib/aolserver/$OPENACS_SERVICE_NAME cp /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/acs-core-docs/www/files/analog.cfg.txt etc/analog.cfg mkdir www/log cp -r /usr/share/analog-5.32/images www/log/
Edit -
/var/lib/aolserver/$OPENACS_SERVICE_NAME/etc/analog.cfg
and change the variable inHOSTNAME "[my -organisation]"
to reflect your website title. If you +/var/lib/aolserver/$OPENACS_SERVICE_NAME/etc/analog.cfg and change the variable in HOSTNAME "[my +organisation]" to reflect your website title. If you don't want the traffic log to be publicly visible, change -OUTFILE /var/lib/aolserver/$OPENACS_SERVICE_NAME/www/log/traffic.html
to use a private -directory. You'll also need to edit all instances of service0 to your $OPENACS_SERVICE_NAME.Run it.
[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$/usr/share/analog-5.32/analog -G -g/var/lib/aolserver/$OPENACS_SERVICE_NAME/etc/analog.cfg
+OUTFILE /var/lib/aolserver/$OPENACS_SERVICE_NAME/www/log/traffic.html to use a private +directory. You'll also need to edit all instances of service0 to your $OPENACS_SERVICE_NAME.Run it.
[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ /usr/share/analog-5.32/analog -G -g/var/lib/aolserver/$OPENACS_SERVICE_NAME/etc/analog.cfg /usr/share/analog-5.32/analog: analog version 5.32/Unix /usr/share/analog-5.32/analog: Warning F: Failed to open DNS input file /home/$OPENACS_SERVICE_NAME/dnscache: ignoring it (For help on all errors and warnings, see docs/errors.html) /usr/share/analog-5.32/analog: Warning R: Turning off empty Search Word Report -[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$Verify that it works by browing to
http://yourserver.test:8000/log/traffic.html
Automate this by creating a file in -
/etc/cron.daily
.[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$exit
+[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$Verify that it works by browing to http://yourserver.test:8000/log/traffic.html
Automate this by creating a file in + /etc/cron.daily.
[$OPENACS_SERVICE_NAME $OPENACS_SERVICE_NAME]$ exit logout -[root root]#emacs /etc/cron.daily/analog
Put this into the file:
#!/bin/sh +[root root]# emacs /etc/cron.daily/analogPut this into the file:
#!/bin/sh -/usr/share/analog-5.32/analog -G -g/var/lib/aolserver/$OPENACS_SERVICE_NAME/etc/analog.cfg
[root root]#chmod 755 /etc/cron.daily/analog
Test it by running the script.
[root root]#sh /etc/cron.daily/analog
Browse to
http://yourserver.test/log/traffic.html
Prev | Home | Next |
Installing SSL Support for an OpenACS service | Up | External uptime validation |
[root root]# chmod 755 /etc/cron.daily/analog
Test it by running the script.
[root root]# sh /etc/cron.daily/analog
Browse to http://yourserver.test/log/traffic.html
Prev | Home | Next |
Installing SSL Support for an OpenACS service | Up | External uptime validation |
by Vinod Kurup
+ +by Vinod Kurup
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -We recommend the use of AOLserver 4.0.1 or later. These instructions are retained as a resource.
+
We recommend the use of AOLserver 4.0.1 or later. These instructions are retained as a resource.
Debian users: we do not recommend installing Debian packages for Aolserver or Postgres. Several people have reported problems while trying to install using apt-get instead of from source. If you have the time to debug these and submit what you did, that's great, but if not, you should stick to installing from source. -
Unpack the Aolserver tarball. Download the aolserver tarball and unpack it.
[root root]#cd /usr/local/src
-[root src]#wget --passive http://uptime.openacs.org/aolserver-openacs/aolserver3.3oacs1.tar.gz
+
Unpack the Aolserver tarball. Download the aolserver tarball and unpack it.
[root root]# cd /usr/local/src +[root src]# wget --passive http://uptime.openacs.org/aolserver-openacs/aolserver3.3oacs1.tar.gz --15:38:08-- http://uptime.openacs.org/aolserver-openacs/aolserver3.3oacs1.tar.gz => `aolserver3.3oacs1.tar.gz' Resolving uptime.openacs.org... done. @@ -21,41 +21,41 @@ 100%[====================================>] 3,858,074 66.56K/s ETA 00:00 15:39:05 (66.56 KB/s) - `aolserver3.3oacs1.tar.gz' saved [3858074/3858074] -[root src]#tar xzf aolserver3.3oacs1.tar.gz
+[root src]# tar xzf aolserver3.3oacs1.tar.gz [root src]# cd /usr/local/src wget --passive http://uptime.openacs.org/aolserver-openacs/aolserver3.3oacs1.tar.gz -tar xzf aolserver3.3oacs1.tar.gzThis section also relies on some OpenACS files, which you can get with Unpack the OpenACS tarball.
Compile AOLserver. Compile and install AOLserver. First, prepare the installation directory and the source code. The message about BUILD-MODULES can be ignored.
root@yourserver root]#mkdir -p /usr/local/aolserver
-[root root]#cd /usr/local/src/aolserver
-[root aolserver]#./conf-clean
+tar xzf aolserver3.3oacs1.tar.gzThis section also relies on some OpenACS files, which you can get with Section , “Unpack the OpenACS tarball”.
Compile AOLserver. Compile and install AOLserver. First, prepare the installation directory and the source code. The message about BUILD-MODULES can be ignored.
root@yourserver root]# mkdir -p /usr/local/aolserver +[root root]# cd /usr/local/src/aolserver +[root aolserver]# ./conf-clean cat: BUILD-MODULES: No such file or directory Done. [root aolserver]#mkdir -p /usr/local/aolserver cd /usr/local/src/aolserver ./conf-clean
If you are using Oracle, edit -
conf-db
and change -postgresql
to -oracle
, or to the word -both
if you want both drivers + conf-db and change + postgresql to + oracle, or to the word + both if you want both drivers installed. In order to get nsoracle to compile, you may need to su - oracle, and then su (without the -) root to set the environment variables properly. -
conf-inst
should contain the +conf-inst should contain the location where AOLserver is to be installed. Overwrite the - tarball's default value with our default value,
/usr/local/aolserver
:[root aolserver]#echo "/usr/local/aolserver" > conf-inst
-[root aolserver]#
conf-make
should contain the + tarball's default value with our default value, /usr/local/aolserver:[root aolserver]# echo "/usr/local/aolserver" > conf-inst +[root aolserver]#conf-make should contain the name of the GNU Make command on your system. It defaults to -
gmake
. Debian users:.
ln -s /usr/bin/make /usr/bin/gmake
Set an environment variable that the nspostgres driver + gmake. Debian users: ln -s /usr/bin/make /usr/bin/gmake.
Set an environment variable that the nspostgres driver Makefile needs to compile correctly and run -
conf
, which compiles + conf, which compiles AOLserver, the default modules, and the database driver, and installs them.Debian users, see warning above, but if you do use apt-get for AOLserver 3.3+ad13 and postgresql from apt-get may need to - make these symlinks:
ln -s - /usr/include/postgresql/ /usr/include/pgsql
- andln -s /usr/lib/postgresql /usr/local/pgsql
)[root aolserver]#export POSTGRES=/usr/local/pgsql; ./conf
+ make these symlinks: ln -s + /usr/include/postgresql/ /usr/include/pgsql + and ln -s /usr/lib/postgresql /usr/local/pgsql)[root aolserver]# export POSTGRES=/usr/local/pgsql; ./conf Building in /usr/local/aolserver with the following modules: aolserver @@ -77,27 +77,27 @@ ================================================================== Done Building Sat Mar 8 10:31:35 PST 2003 [root aolserver]#- This takes about 5 minutes. It builds aolserver, several modules, and the database driver. (Upgraders, note that the postgres database driver has changed from postgres.so to nspostgres.so). All of the results are logged to files in
/usr/local/src/aolserver/log
. If you run into problems running AOLserver, check these files for build errors.Add a database-specific wrapper script. This script + This takes about 5 minutes. It builds aolserver, several modules, and the database driver. (Upgraders, note that the postgres database driver has changed from postgres.so to nspostgres.so). All of the results are logged to files in /usr/local/src/aolserver/log. If you run into problems running AOLserver, check these files for build errors.
Add a database-specific wrapper script. This script sets database environment variables before starting AOLserver; this allows the AOLserver instance can communicate with the database. There is one script each for Oracle and PostgreSQL. They don't conflict, so if you plan - to use both databases, install both.
Oracle
[root aolserver]#cd /usr/local/aolserver/bin
-[root bin]#cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle
-[root bin]#chmod 750 nsd-oracle
+ to use both databases, install both.
Oracle
[root aolserver]# cd /usr/local/aolserver/bin +[root bin]# cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle +[root bin]# chmod 750 nsd-oracle [root bin]# cd /usr/local/aolserver/bin cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-oracle.txt ./nsd-oracle -chmod 750 nsd-oracle
PostgreSQL
[root aolserver]#cd /usr/local/aolserver/bin
-[root bin]#cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres
-[root bin]#chmod 755 nsd-postgres
+chmod 750 nsd-oraclePostgreSQL
[root aolserver]# cd /usr/local/aolserver/bin +[root bin]# cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres +[root bin]# chmod 755 nsd-postgres [root bin]# cd /usr/local/aolserver/bin cp /var/tmp/openacs-5.6.0/packages/acs-core-docs/www/files/nsd-postgres.txt ./nsd-postgres -chmod 755 nsd-postgres
Install tDOM. Download the tDOM +chmod 755 nsd-postgres
Install tDOM. Download the tDOM tarball, unpack it, adjust the configuration file to match our patched - distribution of aolserver, and compile it.
[root root]#cd /usr/local/src
-[root src]#wget --passive http://www.tdom.org/tDOM-0.7.8.tar.gz
+ distribution of aolserver, and compile it.[root root]# cd /usr/local/src +[root src]# wget --passive http://www.tdom.org/tDOM-0.7.8.tar.gz --16:40:58-- http://www.tdom.org/tDOM-0.7.8.tar.gz => `tDOM-0.7.8.tar.gz' Resolving www.tdom.org... done. @@ -109,54 +109,54 @@ 16:41:04 (138.06 KB/s) - `tDOM-0.7.8.tar.gz' saved [826613/826613] -[root src]#tar xzf tDOM-0.7.8.tar.gz
-[root src]#cd tDOM-0.7.8/unix
+[root src]# tar xzf tDOM-0.7.8.tar.gz +[root src]# cd tDOM-0.7.8/unix [root unix]# cd /usr/local/src wget --passive http://www.tdom.org/tDOM-0.7.8.tar.gz tar xzf tDOM-0.7.8.tar.gz cd tDOM-0.7.8/unixEdit the file CONFIG and change this section:
# ---------------------------------------------------- -# aolsrc="/usr/src/aolserver-3.4" +# aolsrc="/usr/src/aolserver-3.4" # ../configure --enable-threads --disable-tdomalloc \ # --with-aolserver=$aolsrc \ # --with-tcl=$aolsrc/tcl8.3.4/unixto
# ---------------------------------------------------- -aolsrc="/usr/local/src/aolserver/aolserver" +aolsrc="/usr/local/src/aolserver/aolserver" ../configure --enable-threads --disable-tdomalloc \ --with-aolserver=$aolsrc \ - --with-tcl=$aolsrc/tcl8.3.2/unixAnd configure and compile:
[root unix]#sh CONFIG
+ --with-tcl=$aolsrc/tcl8.3.2/unixAnd configure and compile:
[root unix]# sh CONFIG creating cache ./config.cache checking for memmove... yes (many lines omitted) creating Makefile creating tdomConfig.sh -[root unix]#make
+[root unix]# make gcc -pipe -DHAVE_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DTCL_THREADS=1 -DHAVE_GETCWD=1 -DHAVE_OPENDIR=1 -DHAVE_STRSTR=1 -DHAVE_STRTOL=1 (many lines omitted) -Wl,-rpath,/usr/local/lib -o tcldomsh;\ fi -[root unix]#cp libtdom0.7.8.so /usr/local/aolserver/bin/
-[root unix]#cd /usr/local/aolserver/bin/
-[root bin]#ln -s libtdom0.7.8.so libtdom.so
+[root unix]# cp libtdom0.7.8.so /usr/local/aolserver/bin/ +[root unix]# cd /usr/local/aolserver/bin/ +[root bin]# ln -s libtdom0.7.8.so libtdom.so [root bin]# sh CONFIG make cp libtdom0.7.8.so /usr/local/aolserver/bin/ cd /usr/local/aolserver/bin -ln -s libtdom0.7.8.so libtdom.soInstall nsopenssl - (OPTIONAL)
Install Full Text Search with OpenFTS (OPTIONAL)
Install nspam (OPTIONAL)
Test AOLserver. In order to test AOLserver, we'll run it using the +ln -s libtdom0.7.8.so libtdom.so
Install nsopenssl + (OPTIONAL)
Install Full Text Search with OpenFTS (OPTIONAL)
Install nspam (OPTIONAL)
Test AOLserver. In order to test AOLserver, we'll run it using the sample-config.tcl file provided in the AOLserver distribution, - under the nobody user and
web
+ under the nobody user and web group. The sample-config.tcl configuration writes to the default log locations, so we need to give it permission to do so - or it will fail. Grant theweb
+ or it will fail. Grant the web group permission to write to -/usr/local/aolserver/log
and -/usr/local/aolserver/servers
.[root root]#cd /usr/local/aolserver
-[root aolserver]#chown -R root.web log servers
-[root aolserver]#chmod -R g+w log servers
-[root aolserver]#ls -l
+ /usr/local/aolserver/log and + /usr/local/aolserver/servers.[root root]# cd /usr/local/aolserver +[root aolserver]# chown -R root.web log servers +[root aolserver]# chmod -R g+w log servers +[root aolserver]# ls -l total 32 drwxr-sr-x 2 root root 4096 Mar 8 12:57 bin drwxr-xr-x 3 root root 4096 Mar 8 10:34 include @@ -171,12 +171,12 @@ chown -R root.web log servers chmod -R g+w log servers ls -lNote: AOLserver4.x does not include a default start page, so we create one for this test. Type -
echo "Welcome to AOLserver" > /usr/local/aolserver40r8/servers/server1/pages/index.html
+ echo "Welcome to AOLserver" > /usr/local/aolserver40r8/servers/server1/pages/index.htmlNow, we'll run a quick test to ensure AOLserver is running correctly. We'll use the sample config file provided with AOLserver. This file will attempt to guess your IP address and hostname. It will then start up the server at port 8000 of that - IP address.
[root aolserver]#./bin/nsd -t sample-config.tcl -u nobody -g web
+ IP address.[root aolserver]# ./bin/nsd -t sample-config.tcl -u nobody -g web [root aolserver]# [08/Mar/2003:15:07:18][31175.8192][-main-] Notice: config.tcl: starting to read config file... [08/Mar/2003:15:07:18][31175.8192][-main-] Warning: config.tcl: nsssl not loaded -- key/cert files do not exist. [08/Mar/2003:15:07:18][31175.8192][-main-] Warning: config.tcl: nscp not loaded @@ -185,32 +185,32 @@ config file.The first warning, about nsssl, can be ignored. We won't be using nsssl; we'll be using nsopenssl instead, and we haven't fully configured it yet. The nscp warning refers to the fact that, without a user and password in the config file, the administrative panel of AOLserver won't load. We don't plan to use it and can ignore that error as well. Any other warning or error is unexpected and probably a problem.
Test to see if AOLserver is working by starting -
Mozilla
or -Lynx
on the same + Mozilla or + Lynx on the same computer and surfing over to your web page. If you browse from another computer and the sample config file didn't guess your hostname or ip correctly, you'll get a false negative test. -[root aolserver]#lynx localhost:8000
+
[root aolserver]# lynx localhost:8000- You should see a "Welcome to AOLserver" page. If this + You should see a "Welcome to AOLserver" page. If this doesn't work, try going to -
http://127.0.0.1:8000/
. If this - still doesn't work, check out the Troubleshooting AOLserver section below. Note that you will not be able to browse to the web page from another machine, because AOLserver is only listening to the local address. + http://127.0.0.1:8000/. If this + still doesn't work, check out the Troubleshooting AOLserver section below. Note that you will not be able to browse to the web page from another machine, because AOLserver is only listening to the local address. -Shutdown the test server:
[root aolserver]#killall nsd
+Shutdown the test server:
[root aolserver]# killall nsd [root aolserver]#- The
killall
command will kill - all processes with the namensd
, + The killall command will kill + all processes with the name nsd, but clearly this is not a good tool to use for managing your - services in general. We cover this topic in the Keep AOLserver alive section. + services in general. We cover this topic in the Keep AOLserver alive section. -Troubleshooting. If you can't view the welcome page, it's likely there's a +
Troubleshooting. If you can't view the welcome page, it's likely there's a problem with your server configuration. Start by viewing your AOLserver log, which is in -
/usr/local/aolserver/log/server.log
. + /usr/local/aolserver/log/server.log. You should also try to find lines of the form:[01/Jun/2000:12:11:20][5914.4051][-nssock-] Notice: nssock: listening on http://localhost.localdomain:8000 (127.0.0.1:8000) @@ -219,12 +219,12 @@ If you can find these lines, try entering the URL the server is listening on. If you cannot find these lines, there must be an error somewhere in the file. Search for lines beginning with the word -Error
instead of -Notice
. + Error instead of + Notice.- The
sample-config.tcl
file grabs + The sample-config.tcl file grabs your address and hostname from your OS settings.@@ -234,11 +234,11 @@ If you get an error that nssock can't get the requested address, you can set these manually. If you type 0.0.0.0, AOLserver will try to listen on all available addresses. Note: -ns_info address
doesn't appear + ns_info address doesn't appear to be supported in current versions of AOLserver.set hostname [ns_info hostname] #set address [ns_info address] -set address 0.0.0.0Install - Analog web file analyzer. (OPTIONAL)
($Id$)
Prev | Home | Next |
Install LDAP for use as external authentication | Up | Appendix C. Credits |
Install + Analog web file analyzer. (OPTIONAL)
Prev | Home | Next |
Install LDAP for use as external authentication | Up | Part III. For OpenACS Package Developers |
By Bryan Quinn
+ +By Bryan Quinn
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Tcl API
-apm-install-procs.tcl (Supports installation of packages)
-20-apm-load-procs.tcl (Bootstraps APM for server startup)
-apm-admin-procs.tcl (Supports APM UI)
PL/SQL file
Tcl API
+apm-install-procs.tcl (Supports installation of packages)
+20-apm-load-procs.tcl (Bootstraps APM for server startup)
+apm-admin-procs.tcl (Supports APM UI)
PL/SQL file
+In general terms, a package is a unit of software that serves a single well-defined purpose. That purpose may be to provide a service directly to one or more classes of end-user, (e.g., discussion forums and file storage for community members, user profiling tools for the site publisher), or it may be to act as a building block for other packages (e.g., an application programming interface (API) for storing and querying access control rules, or an API for scheduling email alerts). Thus, packages fall into one of two categories: -
OpenACS Applications: a "program or group of programs -designed for end users" (the Webopedia +
OpenACS Applications: a "program or group of programs +designed for end users" (the Webopedia definition); also known as modules, for historical reasons. -Examples of applications include Forums and News. +Examples of applications include Forums and News. -
OpenACS Services: the aforementioned building blocks. -Examples of services include the OpenACS -Content Repository, the OpenACS Templating -System, and the OpenACS Kernel, which includes +
OpenACS Services: the aforementioned building blocks. +Examples of services include the OpenACS +Content Repository, the OpenACS Templating +System, and the OpenACS Kernel, which includes APM.
An installation of the OpenACS includes the OpenACS Kernel, some services that extend the kernel's functionality, and some applications intended for -end-users. Packages function as individual pieces of subsites. A subsite can contain multiple +end-users. Packages function as individual pieces of subsites. A subsite can contain multiple application and service instances that provide the end-user with capabilities and content customized to the particular subsite.
This architecture supports the growth of collaborative commerce. For example, Jane User starts a forum focusing on the merits of View Cameras by @@ -36,48 +36,48 @@ it in his subsite. As interest in Jane's forum grows, she creates a subsite specializing in providing information about View cameras. This subsite now includes several package instances beyond Forum; it could -potentially include its own Ecommerce capabilities (ala Yahoo! Shopping). This could include a +potentially include its own Ecommerce capabilities (ala Yahoo! Shopping). This could include a knowledge management application that allows users to spread expertise about view cameras and a portal application that links to reliable camera models and resellers. Any subsite enabled package that is added to the OpenACS installation through APM is another potential package instance that can become part of Jane's View Camera subsite.
The APM provides an architecture for packaging software, making instances of that software available to subsites, specifying configuration parameters -for each instance, and managing the creation and release of new packages.
+for each instance, and managing the creation and release of new packages.
Prior to ACS 3.3, all packages were lumped together into one monolithic distribution without explicit boundaries; the only way to ascertain what comprised a given package was to look at the top of the corresponding documentation page, where, by convention, the package developer would specify where to find: -
the data model
the Tcl procedures
the user-accessible pages
the administration pages
Experience has shown us that this lack of explicit boundaries causes a -number of maintainability problems for pre-3.3 installations:
Package interfaces were not guaranteed to be stable in any formal way, so +
the data model
the Tcl procedures
the user-accessible pages
the administration pages
Experience has shown us that this lack of explicit boundaries causes a +number of maintainability problems for pre-3.3 installations:
Package interfaces were not guaranteed to be stable in any formal way, so a change in the interface of one package would often break dependent packages (which we would only discover through manual regression testing). In this context, any of the following could constitute an interface change: -
renaming a file or directory that appears in a URL
changing what form variables are expected as input by a page
changing a procedural abstraction, e.g., a PL/SQL or Java stored -procedure or a Tcl procedure
changing a functional abstraction, e.g., a database view or a PL/SQL or -Java stored function
changing the data model
This last point is especially important. In most cases, changing the data +
renaming a file or directory that appears in a URL
changing what form variables are expected as input by a page
changing a procedural abstraction, e.g., a PL/SQL or Java stored +procedure or a Tcl procedure
changing a functional abstraction, e.g., a database view or a PL/SQL or +Java stored function
changing the data model
This last point is especially important. In most cases, changing the data model should not affect dependent packages. Rather, the package interface should provide a level of abstraction above the data model (as well as the rest of the package implementation). Then, users of the package can take advantage of implementation improvements that don't affect the interface (e.g., faster performance from intelligent denormalization of the data model), without having to worry that code outside the package will now -break.
A typical ACS-backed site only uses a few of the modules included in the +break.
A typical ACS-backed site only uses a few of the modules included in the distribution, yet there was no well-understood way to pick only what you needed when installing the ACS, or even to uninstall what you didn't need, post-installation. Unwanted code had to be removed manually. -
Releasing a new version of the ACS was complicated, owing again to the +
Releasing a new version of the ACS was complicated, owing again to the monolithic nature of the software. Since we released everything in the ACS together, all threads of ACS development had to converge on a single deadline, after which we would undertake a focused QA effort whose scale increased in direct proportion to the expansion of the ACS codebase. -
There was no standard way for developers outside of ArsDigita to extend +
There was no standard way for developers outside of ArsDigita to extend the ACS with their own packages. Along the same lines, ArsDigita programmers working on client projects had no standard way to keep custom development cleanly separated from ACS code. Consequently, upgrading an already installed @@ -88,43 +88,43 @@ packages for other OpenACS users to download and install.
For a simple illustration of the difference between ACS without APM (pre-3.3) and ACS with APM (3.3 and beyond), consider a hypothetical ACS installation that uses only two of the thirty-odd modules available circa ACS -3.2 (say, bboard and e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS -service that is the only mandatory component of an OpenACS installation.
The OpenACS is a platform for web-based application software, and any software +3.2 (say, bboard and e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS +service that is the only mandatory component of an OpenACS installation.
The OpenACS is a platform for web-based application software, and any software platform has the potential to develop problems like those described above. Fortunately, there are many precedents for systematic solutions, -including:
Borrowing from all of the above, OpenACS 3.3 introduces its own package -management system, the OpenACS Package Manager (APM), which consists of:
a standard format for APM packages (also called -"OpenACS packages"), including:
version numbering, independent of any other package and the OpenACS as a -whole
specification of the package interface
specification of dependencies on other packages (if any)
attribution (who wrote it) and ownership (who maintains it)
web-based tools for package management:
obtaining packages from a remote distribution point
installing packages, if and only if:
all prerequisite packages are installed
no conflicts will be created by the installation
configuring packages (obsoleting the monolithic OpenACS configuration -file)
upgrading packages, without clobbering local modifications
uninstalling unwanted packages
a registry of installed packages, database-backed and +including:
Borrowing from all of the above, OpenACS 3.3 introduces its own package +management system, the OpenACS Package Manager (APM), which consists of:
a standard format for APM packages (also called +"OpenACS packages"), including:
version numbering, independent of any other package and the OpenACS as a +whole
specification of the package interface
specification of dependencies on other packages (if any)
attribution (who wrote it) and ownership (who maintains it)
web-based tools for package management:
obtaining packages from a remote distribution point
installing packages, if and only if:
all prerequisite packages are installed
no conflicts will be created by the installation
configuring packages (obsoleting the monolithic OpenACS configuration +file)
upgrading packages, without clobbering local modifications
uninstalling unwanted packages
a registry of installed packages, database-backed and integrated with filesystem-based version control -
web-based tools for package development:
creating new packages locally
releasing new versions of locally-created packages
The design chosen for APM was meant to satisfy the following constraints: -
The process of authoring a package must be as simple as possible.
Strict conventions must be established that provide a set of canonical +
The process of authoring a package must be as simple as possible.
Strict conventions must be established that provide a set of canonical locations and names for files and patterns, for OpenACS application -development.
The processes of installing, upgrading, and using packages must be -straightforward and accessible through a web-based UI.
Package instances must be able to have subsite-specific content available +development.
The processes of installing, upgrading, and using packages must be +straightforward and accessible through a web-based UI.
Package instances must be able to have subsite-specific content available at an easily configurable URL.
All of these requirements were met, but at the cost of development -simplicity. As Packages demonstrates, a set of strict directory conventions are +simplicity. As Packages demonstrates, a set of strict directory conventions are required in order for a package to use APM. This contrasts with the apparent simplicity available to developers of the OpenACS 3.3 system. However, while the system has become more complex for developers to build packages, this complexity is easily managed and is compensated for by additional capabilities.
For example, to make a new application available to the system, a -developer must:
Create the necessary files to support the data model, Tcl API, and UI -pages.
Put the files in the correct locations for APM to be aware of them.
Use APM to create a new package and enable it.
Use the Site Map facility to create an instance of the package, mount it +developer must:
Create the necessary files to support the data model, Tcl API, and UI +pages.
Put the files in the correct locations for APM to be aware of them.
Use APM to create a new package and enable it.
Use the Site Map facility to create an instance of the package, mount it on an appropriate URL, and set parameters for that particular instance.
While this is complex, especially to a new OpenACS developer, the documentation walks the developer through each of these steps. Moreover, from following these steps, the package can be subsite specific, available to subsites across the system, and be available for distribution to other OpenACS -installations without doing a monolithic upgrade or reinstall.
The APM is composed of systems for accomplishing a set of package-related +installations without doing a monolithic upgrade or reinstall.
The APM is composed of systems for accomplishing a set of package-related tasks. Each of these tasks comprise a feature area that has an API, data -model, and a UI:
Authoring a Package
Maintaining Multiple Versions of a Package
Creating Instances of the Package
Specifying Configuration Parameters for each Instance
Authoring a Package
Full instructions on how to prepare an OpenACS package are available in Packages. The API here can be invoked manually by a package's data model -creation script, but need not to be used. This API is part of the APM PL/SQL +model, and a UI:
Authoring a Package
Maintaining Multiple Versions of a Package
Creating Instances of the Package
Specifying Configuration Parameters for each Instance
Authoring a Package
Full instructions on how to prepare an OpenACS package are available in Packages. The API here can be invoked manually by a package's data model +creation script, but need not to be used. This API is part of the APM PL/SQL package.
-- Informs the APM that this application is available for use. @@ -144,9 +144,9 @@
The procedure above registers an OpenACS application in the APM. It creates a
new OpenACS object and stores information about the package, such as its name, in
the APM data model. There is an analogous procedure for OpenACS services, called
-apm.register_service
.
To remove an application from the system, there are the calls
-apm.unregister_application
and
-apm.unregister_service
.
+apm.register_service.To remove an application from the system, there are the calls +apm.unregister_application and +apm.unregister_service.
-- Remove the application from the system. procedure unregister_application ( @@ -155,22 +155,22 @@ cascade_p in char default 'f' ); -Use the
cascade_p
only if you want to completely remove the +
Use the cascade_p only if you want to completely remove the package from the OpenACS.
In order to determine if a particular package exists in the system, use
-the register_p
predicate. It returns 1 if the specified
-package_key
exists in the system, 0 otherwise.
+the register_p predicate. It returns 1 if the specified +package_key exists in the system, 0 otherwise.function register_p ( package_key in apm_package_types.package_key%TYPE ) return integer; -Maintaining Multiple Versions of a Package
While the package authoring API provides a means for registering a +
Maintaining Multiple Versions of a Package
While the package authoring API provides a means for registering a
package, some information about a package is version dependent. For example,
between versions, the owner of a package, its vendor, its URI, and its
dependency information may change. The API for package versions allows this
-information to be specified. All of these APIs are part of the
-apm_package_version
PL/SQL package.
To create a new package version, use the
-apm_package_version.new
constructor function.
+information to be specified. All of these APIs are part of the +apm_package_version PL/SQL package.To create a new package version, use the +apm_package_version.new constructor function.
function new ( version_id in apm_package_versions.version_id%TYPE @@ -191,26 +191,26 @@ default 'f' ) return apm_package_versions.version_id%TYPE; -In order to use this function, an existing
package_key
must -be specified. Theversion_name
parameter must follow a strict -convention:
A major version number
at least one minor version number. Although any number of minor version +
In order to use this function, an existing package_key must +be specified. The version_name parameter must follow a strict +convention:
A major version number
at least one minor version number. Although any number of minor version numbers may be included, three minor version numbers is sufficient and is the -convention of software developers.
One of the following:
The letter
d
, indicating a development-only versionThe letter
a
, indicating an alpha releaseThe letter
b
, indicating a beta releaseNo letter at all, indicating a final production release
In addition, the letters
d
,a
, and -b
may be followed by another integer, indicating a version +convention of software developers.One of the following:
The letter d, indicating a development-only version
The letter a, indicating an alpha release
The letter b, indicating a beta release
No letter at all, indicating a final production release
In addition, the letters d, a, and +b may be followed by another integer, indicating a version within the release.
For those who like regular expressions:
version_number := ^[0-9]+((\.[0-9]+)+((d|a|b|)[0-9]?)?)$ -So the following is a valid progression for version numbers:
0.9d, 0.9d1, 0.9a1, 0.9b1, 0.9b2, 0.9, 1.0, 1.0.1, 1.1b1, -1.1
To delete a given version of a package, use the -
apm_package_version.delete
procedure:+So the following is a valid progression for version numbers:
0.9d, 0.9d1, 0.9a1, 0.9b1, 0.9b2, 0.9, 1.0, 1.0.1, 1.1b1, +1.1
To delete a given version of a package, use the +apm_package_version.delete procedure:
procedure delete ( package_id in apm_packages.package_id%TYPE );After creating a version, it is possible to edit the information -associated with it using
apm_package_version.edit
.+associated with it using apm_package_version.edit.function edit ( new_version_id in apm_package_versions.version_id%TYPE @@ -244,8 +244,8 @@ );Files associated with a version can be added and removed. The path is -relative to the package-root which is -
acs-server-root/packages/package-key
.+relative to the package-root which is +acs-server-root/packages/package-key.-- Add a file to the indicated version. function add_file( file_id in apm_package_files.file_id%TYPE @@ -326,7 +326,7 @@ version_name_two in apm_package_versions.version_name%TYPE ) return integer; -Creating Instances of a Package
Once a package is registered in the system, it is possible to create +
Creating Instances of a Package
Once a package is registered in the system, it is possible to create instances of it. Each instance can maintain its own content and parameters.
@@ -353,7 +353,7 @@Just creating a package instance is not sufficient for it to be served from the web server. A corresponding site node must be created for it. As an -example, here is how the OpenACS API Documentation service +example, here is how the OpenACS API Documentation service makes itself available on the OpenACS main site:
declare @@ -381,15 +381,15 @@ show errors -Specifying Configuration Parameters for each Instance
A parameter is a setting that can be changed on a package instance basis. -Parameters are registered on each
package_key
, and the values +Specifying Configuration Parameters for each Instance
A parameter is a setting that can be changed on a package instance basis. +Parameters are registered on each package_key, and the values are associated with each instance. Parameters can have default values and can be of type 'string' or 'number.' There is support with this API for setting a number of minimum and maximum values for each parameter, but for most instances, the minimum and maximum should be 1. It is useful to allow or require multiple values for packages that need to store multiple pieces of information under one parameter. Default values are automatically -set when instances are created, but can be changed for each instance.
All of the functions below are in the APM PL/SQL +set when instances are created, but can be changed for each instance.
All of the functions below are in the APM PL/SQL package.
-- Indicate to APM that a parameter is available to the system. @@ -463,65 +463,65 @@ attr_value in apm_parameter_values.attr_value%TYPE ); -
The central piece of the data model is the apm_package_types
table where each package is registered. When a new application or service is
installed on an OpenACS instance, a corresponding row in this table is inserted
-with information about the type of package, e.g. if the forum package is installed on your OpenACS server, a row
-in apm_package_types
will be created, noting that it's an
-application package type.
The apm_packages
table is used to contain information about
+with information about the type of package, e.g. if the forum package is installed on your OpenACS server, a row
+in apm_package_types will be created, noting that it's an
+application package type.
The apm_packages table is used to contain information about
the instances of packages currently created in the system. The
-package_key
column references the apm_package_types
+package_key column references the apm_package_types
table to ensure that no package instance can be created for a type that does
-not exist.
The apm_package_versions
table contains information specific
+not exist.
The apm_package_versions table contains information specific to a particular version of a package. Several tables reference this one to -provide further information about the particular version:
apm_package_owners
+provide further information about the particular version:
apm_package_owners Stores information about the owners of a particular version of a package. -
apm_package_files
+
apm_package_files Stores information about the files that are part of a version. -
apm_package_dependencies
+
apm_package_dependencies Stores information about what interfaces the package provides and -requires.
Parameter information is maintained through two tables:
apm_parameters
+requires.
Parameter information is maintained through two tables:
apm_parameters This table contains the definition of each of the parameters for a package. -
apm_parameter_values
+
apm_parameter_values This table holds all of the values of parameters for specific package instances.
A number of views are available for obtaining information about packages -registered in the APM.
apm_package_version_info
+registered in the APM.
apm_package_version_info
Provides information about all of the versions in the system with
-information available from the apm_package_types
table.
+information available from the apm_package_types table.
-
apm_enabled_package_versions
+
apm_enabled_package_versions A view (subset) of the above table with only enabled versions. -
apm_file_info
- Provides a public interface for querying file information.
The APM's user interface is part of the -OpenACS Administration Service. The UI is the primary +
apm_file_info + Provides a public interface for querying file information.
The APM's user interface is part of the +OpenACS Administration Service. The UI is the primary point of contact with APM by developers and administrators. It is part of OpenACS Administration, because only the site-wide administrator should be able to access it. Thus in order to develop a package, the developer must be granted -site-wide administration.
APM has two parameters for configuring how it interacts with the UNIX -filesystem, accessible via the Site Map admin +site-wide administration.
APM has two parameters for configuring how it interacts with the UNIX +filesystem, accessible via the Site Map admin page. These parameters need not be changed under most circumstances, but may -need to be tweaked for Windows compatibility.
GzipExecutableDirectory
- This directory points to where the gunzip
program can be found
-for uncompressing gzip
archives. This is needed for the
-installation of .apm
files which are simply gzip
ed
-tarballs. Default is /usr/local/bin
+need to be tweaked for Windows compatibility.
GzipExecutableDirectory + This directory points to where the gunzip program can be found +for uncompressing gzip archives. This is needed for the +installation of .apm files which are simply gziped +tarballs. Default is /usr/local/bin -
InfoFilePermissionsMode +
InfoFilePermissionsMode This sets the default UNIX permissions used when creating files using the -APM. Default is 775.
APM has been in production since OpenACS 3.3, and as of version 4.0 offers a stable set of features. One major feature planned is integration with the OpenACS Package Repository for automatic dependency satisfaction. When a user tries to install a package that depends on other packages, the APM will contact the @@ -539,6 +539,6 @@ repositories worldwide.
Another anticipated change is to split the APM UI into separate systems for authoring, maintaining, and installing packages. The current UI presents all of this functionality in one interface and it can be confusing from a -usability perspective.
System creator: Bryan Quinn, Jon Salz, Michael Yoon, Lars Pind, Todd -Nightingale.
System owner: Bryan Quinn
Documentation author: Bryan Quinn, building from earlier versions by Jon -Salz, Michael Yoon, and Lars Pind.
System creator: Bryan Quinn, Jon Salz, Michael Yoon, Lars Pind, Todd +Nightingale.
System owner: Bryan Quinn
Documentation author: Bryan Quinn, building from earlier versions by Jon +Salz, Michael Yoon, and Lars Pind.
By Bryan Quinn and Todd Nightingale
+ +By Bryan Quinn and Todd Nightingale
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -The following is a requirements document for the OpenACS Package Manager (APM), version 4.0 (APM4). APM4 offers a superset of APM v3.3 functionality -with the following specific enhancements:
A public procedural API. (v 3.3 only has web-based UI)
Support for dependency checking.
Support for compound packages (to support installation chaining).
Support for on-line parameter setting.
Support for sub-site level configuration (requires revised parameter +with the following specific enhancements:
A public procedural API. (v 3.3 only has web-based UI)
Support for dependency checking.
Support for compound packages (to support installation chaining).
Support for on-line parameter setting.
Support for sub-site level configuration (requires revised parameter and /admin pages at sub-site level; deprecation of site-wide parameter file).
To differentiate these new requirements from the requirements of version 3.3, all requirements new in v4 are prefaced with the number -4.
We gratefully acknowledge the authors of APM 3 for their original design +4.
We gratefully acknowledge the authors of APM 3 for their original design documentation which suggested these features, as well as the influence of the design and open-source implementation of the Red Hat Package manager, the Debian packaging system, and PERL's CPAN in the development of the ideas -behind this document.
A typical website will tend to offer its users a number of web-based +behind this document.
A typical website will tend to offer its users a number of web-based services or applications, e.g. a bulletin board, calendaring, classified ads, etc. A website may also have underlying subsystems, such as a permissions system, content management system, etc. For such applications and subsystem @@ -26,38 +26,38 @@ OpenACS sites.
In general terms, a package is a unit of software that serves a single well-defined purpose. The OpenACS Package Manager (APM) provides a mechanism for packaging, installing, and configuring OpenACS software in a consistent, -user-friendly, and subsite-aware manner.
The OpenACS Package Manager (APM) consists of: -
A standard format for APM packages including:
Version numbering, independent of any other package and the OpenACS as a -whole
Specification of the package interface
Specification of dependencies on other packages (if any)
Attribution (who wrote it) and ownership (who maintains it)
Web-based tools for package management:
Obtaining packages from a remote distribution point
Installing packages, if and only if:
All prerequisite packages are installed
No conflicts will be created by the installation
Configuring packages (obsoleting the monolithic OpenACS configuration -file)
Upgrading packages, without clobbering local modifications
Uninstalling unwanted packages
A registry of installed packages, database-backed and +
A standard format for APM packages including:
Version numbering, independent of any other package and the OpenACS as a +whole
Specification of the package interface
Specification of dependencies on other packages (if any)
Attribution (who wrote it) and ownership (who maintains it)
Web-based tools for package management:
Obtaining packages from a remote distribution point
Installing packages, if and only if:
All prerequisite packages are installed
No conflicts will be created by the installation
Configuring packages (obsoleting the monolithic OpenACS configuration +file)
Upgrading packages, without clobbering local modifications
Uninstalling unwanted packages
A registry of installed packages, database-backed and integrated with file system-based version control -
Web-based tools for package development:
Creating new packages locally
Releasing new versions of locally-created packages
Uploading packages to a global package repository on the web
Use of these tools should be safe, i.e. installing or removing a package -should never break an OpenACS installation
Web-based tools for package configuration:
The ability to change package parameter values on-line through a simple -web interface.
A new ad_parameter which does not require a monolithic site-wide -parameter's file or server restarts for changes to take effect.
The ability to manage multiple package instances at the sub-site -level.
+
Web-based tools for package development:
Creating new packages locally
Releasing new versions of locally-created packages
Uploading packages to a global package repository on the web
Use of these tools should be safe, i.e. installing or removing a package +should never break an OpenACS installation
Web-based tools for package configuration:
The ability to change package parameter values on-line through a simple +web interface.
A new ad_parameter which does not require a monolithic site-wide +parameter's file or server restarts for changes to take effect.
The ability to manage multiple package instances at the sub-site +level.
The APM is intended for the following classes of users, which may or may not -overlap:
Developers (referred to as 'the developer') use +overlap:
Developers (referred to as 'the developer') use the APM to create a software package for distribution and use the procedural -API for direct control of the APM system.
Site-wide administrators (referred to as 'the +API for direct control of the APM system.
Site-wide administrators (referred to as 'the administrator') use the APM to install packages for their OpenACS instance, -and optionally make them available to sub-sites.
Sub-site administrators (referred to as 'the +and optionally make them available to sub-sites.
Sub-site administrators (referred to as 'the sub-admin') use an administration interface to configure and enable -packages for their sub-site.
Initial Package Development
David Developer writes a piece of software used to do +packages for their sub-site.
Initial Package Development
David Developer writes a piece of software used to do knowledge management (km) for the OpenACS. He distributes his data model, procedure code, UI pages, and his documentation according to the APM specification. He splits the documentation and the code into sub-packages, and creates a KM installation-chain to install both with the APM developer -UI. Noting that his software was built with Patricia -Programmer's Super Widget toolkit, he specifies that as a +UI. Noting that his software was built with Patricia +Programmer's Super Widget toolkit, he specifies that as a dependency. Moreover, since this package is capable of being used at the sub-site level, David configures this option in the package. When the package development is complete, David uses the APM developer UI to construct a distribution file. He assigns it a version number, 1.0, and makes the package -available for download at the OpenACS package repository.
Initial Package Installation
Annie Admin learns of David's KM system by browsing +available for download at the OpenACS package repository.
Initial Package Installation
Annie Admin learns of David's KM system by browsing the OpenACS package repository. Annie Admin uses the APM administrator UI on her system. She selects to install a package from a URL and types the URL displayed on the system. The APM automatically downloads the package. The @@ -71,16 +71,16 @@ installation was successful, the package is available for use.
Since the package is available for use, its initialization routines are set to run automatically on server startup. Annie is warned that since there are initialization routines, she must restart the server for the package to -be ready for use. Annie restarts the server.
Initial Subsite Use of Package
Annie Admin decides to make the KM module available only to a particular +be ready for use. Annie restarts the server.
Initial Subsite Use of Package
Annie Admin decides to make the KM module available only to a particular sub-site type on her OpenACS system, and not others. She specifies this option -using the Sub-site type UI (not part of APM).
Annie Admin notifies Sally SubAdmin by e-mail that a new +using the Sub-site type UI (not part of APM).
Annie Admin notifies Sally SubAdmin by e-mail that a new package is now available for use. Sally goes to her sub-site /admin page and sees that a new entry, KM, is available. Sally clicks on it and finds links to the installed KM documentation and to the web based configuration utility. Then, Sally configures the package using an automatically generated web interface and enables KM for use on her sub-site. After some initial use of the package, Sally decides to change some parameters using the SubAdmin UI. -These changes take effect immediately, without any server restarts.
Upgrade Process
Sally SubAdmin finds a bug in the KM system and sends a report to David +These changes take effect immediately, without any server restarts.
Upgrade Process
Sally SubAdmin finds a bug in the KM system and sends a report to David Developer. David reads the bug report and verifies that the bugs are present in the current version. Because the bugs are present in the shared procedure file, David assigns a watch to the file. David makes the necessary @@ -91,199 +91,199 @@ repository.
Sally SubAdmin asks Annie Administrator to upgrade the package using the APM UI. This upgrade supersedes the old version of KM at the site-wide level. Once Annie upgrades the package, the new version starts working immediately -in Sally's sub-site.
Procedural API
Danielle Developer wants her software to perform +in Sally's sub-site.
Procedural API
Danielle Developer wants her software to perform different actions depending on what version of another package is installed. She uses the APM procedural API to check if KM version 1.0 is installed or version 1.1. Based on the results of this procedural call, the software -exhibits different behavior.
4.500.0 Package Identification -(All of these items are entered by the developer using the developer UI.)
4.500.1 A human readable package key that is guaranteed +exhibits different behavior.
4.500.0 Package Identification +(All of these items are entered by the developer using the developer UI.)
4.500.1 A human readable package key that is guaranteed to be unique to the local OpenACS site must be maintained by the APM. For -example, "apm."
4.500.5 A package id (primary key) that is guaranteed to +example, "apm."
4.500.5 A package id (primary key) that is guaranteed to be unique to the local site must be maintained by the APM. For example, -"25."
4.500.10 A package URL that is guaranteed to be unique +"25."
4.500.10 A package URL that is guaranteed to be unique across all sites must be maintained by the APM. The package URL should point to a server that allows download of the latest version of the package. For -example, "http://openacs.org/software." -
4.505.0 Version Identification - (All of these items are entered by the developer using the developer UI.)
4.505.1 A version id (primary key) that is guaranteed to -be unique to the local site must be maintained by the APM.
4.505.5 A version URL that is guaranteed to be unique +example, "http://openacs.org/software." +
4.505.0 Version Identification + (All of these items are entered by the developer using the developer UI.)
4.505.1 A version id (primary key) that is guaranteed to +be unique to the local site must be maintained by the APM.
4.505.5 A version URL that is guaranteed to be unique across all sites must be maintained by the APM. The version URL should point to a server that allows download of a specific version of the package. -
The API for APM v3 is explicitly a private API. However, it would be useful to obtain information from the APM through a procedural API. Implementing the API specified below is quite easy given that there are pages -that already do all of the below in raw SQL.
4.400.0 Packages Status Predicates
4.400.1 Given defining information such as a package URL, +that already do all of the below in raw SQL.
4.400.0 Packages Status Predicates
4.400.1 Given defining information such as a package URL, the APM API can return the status of the package on the local OpenACS -instance.
4.405.0 Package Information Procedures
4.405.1 The APM API can return information for any +instance.
4.405.0 Package Information Procedures
4.405.1 The APM API can return information for any locally installed packages, including the version number, paths and files, -and package key.
4.410.0 Sub-site Procedures
4.410.1 After a package has been installed at the +and package key.
4.410.0 Sub-site Procedures
4.410.1 After a package has been installed at the site-wide level, the system API will provide means to check for package -presence, creation, enabling, disabling, and destruction on a subsite.
4.415.0 Parameter Values (replaces ad_parameter)
4.415.1 The system API shall allow subsite parameters for +presence, creation, enabling, disabling, and destruction on a subsite.
4.415.0 Parameter Values (replaces ad_parameter)
4.415.1 The system API shall allow subsite parameters for an installed package to be set by either site-wide administrators or sub-site admins. The subsite parameter can be set to be non-persistent (but default is to survive server restarts). The subsite parameter can also be set to only -take effect after a server restart (default is immediate).
4.415.5 Parameters for a given subsite and package can be -returned by the system API.
Provisions will be made to assure that packages are securely -identified.
4.600.1 Each package will have a PGP signature and there +identified.
4.600.1 Each package will have a PGP signature and there will be MD5 time stamps for each file within the package. -
4.600.5 The APM will provide a facility to validate both -the PGP signature and MD5 stamps information before a package install.
The user interface is a set of HTML pages that are used to drive the underlying API. It is restricted to site-wide administrators because the -actions taken here can dramatically affect the state of the running OpenACS.
The intent of the developer's interface is to enable the developer to +actions taken here can dramatically affect the state of the running OpenACS.
The intent of the developer's interface is to enable the developer to construct and maintain APM packages. It will be possible to disable the developer's interface for production sites to help reduce the chance of site failure; much of the functionality here can have cascading effects -throughout the OpenACS and should not be used on a production site.
10.0 Define a package.
The developer must be able to create a new package by specifying some +throughout the OpenACS and should not be used on a production site.
10.0 Define a package.
The developer must be able to create a new package by specifying some identifying information for the package. This includes a package name, a -package key, version information, owner information, and a canonical URL.
10.1 The APM must maintain the state of all locally -generated packages.
10.50 If the developer fails to provide the required -information, the package cannot be created.
10.55 All of the package information should be editable -after creation, except for the package key.
4.10.60 The package creator must specify whether the +package key, version information, owner information, and a canonical URL.
10.1 The APM must maintain the state of all locally +generated packages.
10.50 If the developer fails to provide the required +information, the package cannot be created.
10.55 All of the package information should be editable +after creation, except for the package key.
4.10.60 The package creator must specify whether the package is capable of being used in sub-sites, or if only a single, global -instance of the package is permitted.
4.10.65 If the developer fails to provide unique +instance of the package is permitted.
4.10.65 If the developer fails to provide unique information for unique fields specified in the data model requirements, the -package cannot be created.
20.0 Add files to a package
20.1 The developer must be able to add files to the +package cannot be created.
20.0 Add files to a package
20.1 The developer must be able to add files to the package. This is done by copying the files into the package directory in the host OS's file system. Files can be added at any point after package -creation.
20.3 Once a package has been versioned and distributed, +creation.
20.3 Once a package has been versioned and distributed, no new files should be added to the package without incrementing the version -number.
20.5 The APM's UI should facilitate the process of +number.
20.5 The APM's UI should facilitate the process of adding new files, by scanning the file system for new files automatically, -and allowing the developer to confirm adding them.
20.10 The developer cannot add files to a given package -via the UI that do not exist in the file system already.
20.15 Package file structure must follow a specified -convention. Please see the design -document for what we do currently.
30.0 Remove files from a package
The developer must be able to remove files from a package. This can be -done in two ways.
30.1 Access the APM UI, browse the file list, and remove -files.
30.1.1If a file is removed from the package list, but not -from the file system, an error should be generated at package load time.
30.5 Remove the file from file system.
30.5.1 The APM UI should take note of the fact that the +and allowing the developer to confirm adding them.
20.10 The developer cannot add files to a given package +via the UI that do not exist in the file system already.
20.15 Package file structure must follow a specified +convention. Please see the design +document for what we do currently.
30.0 Remove files from a package
The developer must be able to remove files from a package. This can be +done in two ways.
30.1 Access the APM UI, browse the file list, and remove +files.
30.1.1If a file is removed from the package list, but not +from the file system, an error should be generated at package load time.
30.5 Remove the file from file system.
30.5.1 The APM UI should take note of the fact that the file is gone and offer the developer an option to confirm the file's deletion. -
40.0 Modify files in a package.
40.1 The developer should be able to modify files in the -file system. The APM UI should not interfere with this.
40.5 However, if the developer modifies files containing -procedural definitions, APM UI should allow a means to watch +
40.0 Modify files in a package.
40.1 The developer should be able to modify files in the +file system. The APM UI should not interfere with this.
40.5 However, if the developer modifies files containing +procedural definitions, APM UI should allow a means to watch those files and automatically reload them if changed. See requirement 50.0 -for more detail.
40.10 Also, although a change in files implies that the +for more detail.
40.10 Also, although a change in files implies that the package distribution file is out of date, it is the developer's -responsibility to update it.
4.45.0 Manage Package Dependency Information.
4.45.1 The developer should be able to specify which -interfaces the package requires.
4.45.5 The developer should be able to specify which -interfaces the package provides.
4.45.10 Circular dependencies are not allowed.
50.0 Watch a file
4.50.1 The developer should be able to assign a watch to -any Tcl procedure file, whether in /packages or /tcl.
50.5 If a watched file is locally modified, then it will +responsibility to update it.
4.45.0 Manage Package Dependency Information.
4.45.1 The developer should be able to specify which +interfaces the package requires.
4.45.5 The developer should be able to specify which +interfaces the package provides.
4.45.10 Circular dependencies are not allowed.
50.0 Watch a file
4.50.1 The developer should be able to assign a watch to +any Tcl procedure file, whether in /packages or /tcl.
50.5 If a watched file is locally modified, then it will be automatically reloaded, thus allowing for any changes made to take affect -immediately.
4.50.10 The setting of a watch should be persistent +immediately.
4.50.10 The setting of a watch should be persistent across server restarts. -
60.0 Display an XML package specification
60.1 The developer should be able to view the XML package +
60.0 Display an XML package specification
60.1 The developer should be able to view the XML package specification that encodes all package information. -
70.0 Write an XML package specification to the file -system
70.1 The developer should be able to write an up-to-date -XML specification to disk.
70.5 The developer should be able to request the current -XML specification for all installed, locally generated packages.
130.0 Distribution file generation
130.1 The developer should be able to generate a .APM -distribution file for the package with just one click.
130.5 Generating a distribution file implies doing an -"up-to-date" check on all of the files. If any of the files have +
70.0 Write an XML package specification to the file +system
70.1 The developer should be able to write an up-to-date +XML specification to disk.
70.5 The developer should be able to request the current +XML specification for all installed, locally generated packages.
130.0 Distribution file generation
130.1 The developer should be able to generate a .APM +distribution file for the package with just one click.
130.5 Generating a distribution file implies doing an +"up-to-date" check on all of the files. If any of the files have changed since package installation, then a new version of the package is created. -
140.0 Access CVS information
140.1 The developer should be able to determine the CVS +
140.0 Access CVS information
140.1 The developer should be able to determine the CVS status of a package, or all packages, with a single click. -
4.400.0 Compound Package Construction
4.400.1 The developer can include .APM packages +
4.400.0 Compound Package Construction
4.400.1 The developer can include .APM packages (sub-packages) within a package (the compound package) like any other -file.
4.400.5 The recommended usage for this feature is to +file.
4.400.5 The recommended usage for this feature is to
allow for separation of optional and required components from the
installation as well as better organization of files once installed. For
example, all documentation for the community-core can be packages as
-community-core-doc.apm
. It is legal to include sub-packages with
+community-core-doc.apm. It is legal to include sub-packages with
dependencies that are not satisfied by the packages in the compound package,
but this is discouraged. In such a case, the sub-package should really be a
-separate package that is required by the compound package.
4.400.10 If a sub-package is required for the +separate package that is required by the compound package.
4.400.10 If a sub-package is required for the installation of the compound package, the compound package should have a -registered dependency on the sub-package.
The requirement of the administrator's interface is to enable the administrator to install, enable, upgrade, disable, deinstall, and delete -packages.
80.0 Package Enable/Disable
4.80.1 The administrator should be able mark an installed +packages.
80.0 Package Enable/Disable
4.80.1 The administrator should be able mark an installed package as enabled. This means that the package is activated and its functionality is delivered through the Request Processor. As of OpenACS 4, this -is done through the sub-site system.
4.80.5 Moreover, the administrator must be able to +is done through the sub-site system.
4.80.5 Moreover, the administrator must be able to disable a package, thereby removing the functionality provided to a sub-site. As of OpenACS 4, this is done through the sub-site system. -
90.0 Package Install
90.1 The administrator must be able to install new -packages either from locally maintained .APM files or from URLs.
90.5 In the case of an URL, the APM transparently +
90.0 Package Install
90.1 The administrator must be able to install new +packages either from locally maintained .APM files or from URLs.
90.5 In the case of an URL, the APM transparently downloads the APM file off the web, proceeds with a file based installation, -and then optionally removes the .APM file just downloaded.
90.10.1 If .APM files are present in a package, then it -is considered a compound package (use 4.410.0).
90.15.0 Installation requires these steps:
90.15.1The package dependencies are scanned. If some +and then optionally removes the .APM file just downloaded.
90.10.1 If .APM files are present in a package, then it +is considered a compound package (use 4.410.0).
90.15.0 Installation requires these steps:
90.15.1The package dependencies are scanned. If some dependencies are not present, the system warns the administrator that -installation cannot proceed until those packages are installed.
90.15.2 Assuming all dependencies are present, APM -extracts the contents of the APM file into the /packages directory.
90.15.3 The administrator is offered the option of -importing directly into CVS.
90.15.4 The administrator is given a list of data model -scripts found in the package and can select which ones to be executed.
90.15.5 If no errors are recorded during this process, -the package is enabled.
4.410.0 Compound package Install
4.410.1 If .APM files are present in a package, then it -is considered a compound package.
4.410.5.0 Installation of a compound package proceeds -according to the following sequence:
4.410.5.1 Identify the set of all sub-packages within -the compound package by scanning for all files with .APM.
4.410.5.2 Identify which sub-packages are required by +installation cannot proceed until those packages are installed.
90.15.2 Assuming all dependencies are present, APM +extracts the contents of the APM file into the /packages directory.
90.15.3 The administrator is offered the option of +importing directly into CVS.
90.15.4 The administrator is given a list of data model +scripts found in the package and can select which ones to be executed.
90.15.5 If no errors are recorded during this process, +the package is enabled.
4.410.0 Compound package Install
4.410.1 If .APM files are present in a package, then it +is considered a compound package.
4.410.5.0 Installation of a compound package proceeds +according to the following sequence:
4.410.5.1 Identify the set of all sub-packages within +the compound package by scanning for all files with .APM.
4.410.5.2 Identify which sub-packages are required by checking the dependencies of the compound package. If there dependencies not satisfied by the current system or the packages included with the compound package, halt installation and inform user to install these packages -first.
4.410.5.3 Present Administrator with the ability to +first.
4.410.5.3 Present Administrator with the ability to choose which sub-packages to install. Required sub-packages must be -installed.
4.410.5.4 Proceed with the installation of each +installed.
4.410.5.4 Proceed with the installation of each sub-package, starting with required packages. If the sub-package is already installed, then do nothing. Else, If the sub-package is a normal package, -proceed according to 90.15.0, otherwise if it is a compound -package, proceed according to 4.410.5.0.
4.410.5.5 If all required sub-packages are installed, +proceed according to 90.15.0, otherwise if it is a compound +package, proceed according to 4.410.5.0.
4.410.5.5 If all required sub-packages are installed, proceed to install non-required sub-packages. If there was a failure during the installation of a required sub-package, then the installation of the -compound package is also a failure.
4.410.5.6 Any attempt to install a compound package in +compound package is also a failure.
4.410.5.6 Any attempt to install a compound package in the future involves a choice presented to the admin of installing any -uninstalled sub-packages.
4.420.0 Recovering from failed package installation
4.420.1 If any error is generated during package +uninstalled sub-packages.
4.420.0 Recovering from failed package installation
4.420.1 If any error is generated during package installation, the package is not considered installed. To recover from this -failure, the package should be selected for installation again.
100.0 Version Upgrade
100.1 The administrator can upgrade to a new version of a -package. This entails
100.1.1 Running any necessary and included upgrade -scripts.
100.1.5 Replacing any old files with new versions.
100.1.10 Marking the old version of the package as -'superseded' and disabling it.
100.1.15 Assuming no errors from above, the new package -is enabled.
110.0 Package Deinstall
110.1 The administrator must be able to deinstall a -package that has already been installed. Deinstallation entails:
110.1.1 Running any data model scripts necessary to drop -the package.
110.1.5 Moving all of the files into a separate location -in the file system from the installed packages.
4.110.1.10 If the package is a compound package, then +failure, the package should be selected for installation again.
100.0 Version Upgrade
100.1 The administrator can upgrade to a new version of a +package. This entails
100.1.1 Running any necessary and included upgrade +scripts.
100.1.5 Replacing any old files with new versions.
100.1.10 Marking the old version of the package as +'superseded' and disabling it.
100.1.15 Assuming no errors from above, the new package +is enabled.
110.0 Package Deinstall
110.1 The administrator must be able to deinstall a +package that has already been installed. Deinstallation entails:
110.1.1 Running any data model scripts necessary to drop +the package.
110.1.5 Moving all of the files into a separate location +in the file system from the installed packages.
4.110.1.10 If the package is a compound package, then the administrator must confirm removing all sub-packages. Optionally, some -sub-packages can be kept.
110.5 Deinstalled packages can be re-installed at a later -date.
4.110.10 If deinstalling a package or any of its +sub-packages can be kept.
110.5 Deinstalled packages can be re-installed at a later +date.
4.110.10 If deinstalling a package or any of its sub-packages breaks a dependency, then deinstallation cannot proceed until -the package registering the dependency is removed.
120.0 Package Deletion
120.1 The administrator should be able to completely +the package registering the dependency is removed.
120.0 Package Deletion
120.1 The administrator should be able to completely erase all records of the package. This involves removing all instances of the -package, all related database tables and content.
120.5 This option can only be used if all package +package, all related database tables and content.
120.5 This option can only be used if all package instances are deleted or marked as disabled. This is purposefully cumbersome because deleting all instances of a package can have far-sweeping -consequences throughout a site and should almost never be done.
150.0 Scan for new or modified packages
150.1 The administrator should be able to scan the file -system for any changes made in any of the installed package files.
150.5 The administrator should be able to scan the file +consequences throughout a site and should almost never be done.
150.0 Scan for new or modified packages
150.1 The administrator should be able to scan the file +system for any changes made in any of the installed package files.
150.5 The administrator should be able to scan the file system for any newly installed packages. -
If the developer is in charge of creating packages and the administrator for installing them, then the sub-site administrator is responsible for configuring and enabling packages. In order for a package to be available for a sub-site it must be associated with the sub-site's type specification. This interface is part of the sub-site /admin interface. -
4.300 Creating a package instance.
4.300.1 From the sub-site /admin interface, there should +
4.300 Creating a package instance.
4.300.1 From the sub-site /admin interface, there should be an option to view all packages available in the system as well as an -option to add a package to the subsite.
4.300.5 From the "add" option, the sub-admin +option to add a package to the subsite.
4.300.5 From the "add" option, the sub-admin can select from a list of packages registered as available in the sub-site -type to which the sub-site belongs.
4.300.19 Once a package instance is added, it is -available on the list of the subsite's available packages.
4.305 Configuring a package instance.
4.305.1 An automatic web interface that lists all -parameters with current values must be available.
4.305.5 Changing the values for the parameters is -accomplished simply by submitting an HTML form.
4.310 Enabling a package instance.
4.310.1 The sub-admin should be able to enable a package +type to which the sub-site belongs.
4.300.19 Once a package instance is added, it is +available on the list of the subsite's available packages.
4.305 Configuring a package instance.
4.305.1 An automatic web interface that lists all +parameters with current values must be available.
4.305.5 Changing the values for the parameters is +accomplished simply by submitting an HTML form.
4.310 Enabling a package instance.
4.310.1 The sub-admin should be able to enable a package with a single click. Enabling a package means that the OpenACS will serve its URLs properly. -
4.315 Disabling a package instance.
4.315.1 The sub-admin should be able to disable a package +
4.315 Disabling a package instance.
4.315.1 The sub-admin should be able to disable a package with a single click. Disabling a package means that the OpenACS will no longer -serve those URLs.
4.320 Deleting a package instance.
4.320.1 Deleting a package instance involves deleting not +serve those URLs.
4.320 Deleting a package instance.
4.320.1 Deleting a package instance involves deleting not only the package instance, but any and all content associated with it. It is questionable whether this option should even be available due to its drastic consequences. Reviewer comments appreciated. -
Despite the fact that requirements are meant to be design/implementation neutral, the following thoughts were in our head when specifying these requirements. You must be familiar with the new object design for this to be comprehensible.
When a package is installed system-wide, a corresponding acs_object_type @@ -292,4 +292,4 @@ are set using the acs_attribute_values table. The automatic web interface for setting package parameters should be one and the same with the interface for setting acs object attribute values. Consequently, the implementation of -these features should be quite straightforward.
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su | |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su | |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
By Jeff Davis
+ +By Jeff Davis
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Best practices in writing OpenACS automated tests
Special characters in Tcl.
-Try strings starting with a -Bad
and strings containing [BAD]
, {
, \077
, and $Bad
. For user input, [BAD]
should never be evaluated, \077
should not be turned into a ?
and $Bad
should not be interpolated. The string -Bad [BAD] \077 { $Bad
should be valid user input, should pass through the system unaltered, and if it isn't that's a bug.
-
Quoting issues. Put some html in plain text fields and make sure the result is -properly quoted anywhere it shows up (I use "<b>bold</b>" +
Best practices in writing OpenACS automated tests
Special characters in Tcl. +Try strings starting with a -Bad and strings containing [BAD], {, \077, and $Bad. For user input, [BAD] should never be evaluated, \077 should not be turned into a ? and $Bad should not be interpolated. The string -Bad [BAD] \077 { $Bad should be valid user input, should pass through the system unaltered, and if it isn't that's a bug. +
Quoting issues. Put some html in plain text fields and make sure the result is
+properly quoted anywhere it shows up (I use "<b>bold</b>"
usually). Look out especially for quoting errors in the context bar
and in round trips via an edit form. For fields that disallow html
-tags you can use &
to check that the field is quoted
-properly. If it is not displayed as &
then the quoting for the field is incorrect. (It's not clear whether this
+tags you can use & to check that the field is quoted
+properly. If it is not displayed as & then the quoting for the field is incorrect. (It's not clear whether this
should be considered an error but given that data for text fields can
come from various sources if it's text it should be properly quoted
and we should not rely on input validation to prevent XSS security
-holes.)
Whitespace input. Check that whitespace is not considered valid input for a field +holes.)
Whitespace input. Check that whitespace is not considered valid input for a field
if it does not make sense. For example, the subject of a forum post is
-used to construct a link and if it is " " it will have a link of
-<a href="..."> </a>
which would not be clickable if whitespace was allowed as a valid input.
-
Doubleclick. +used to construct a link and if it is " " it will have a link of +<a href="..."> </a> which would not be clickable if whitespace was allowed as a valid input. +
Doubleclick. Make sure that if you submit a form, use the back button, and submit again that the behavior is reasonable (correct behavior depends on what the form is for, but a server error is not reasonable). -
Duplicate names. +
Duplicate names. Make sure that if a duplicate name is entered that there is a reasonable error rather than a server error. Check for insert, move, copy, and rename. -
By Jon Salz
+ +By Jon Salz
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Tcl code: /tcl/0-acs-init.tcl and /packages/acs-kernel/bootstrap.tcl
This document describes the startup (bootstrapping) process for an AOLserver +
Tcl code: /tcl/0-acs-init.tcl and /packages/acs-kernel/bootstrap.tcl
This document describes the startup (bootstrapping) process for an AOLserver running OpenACS. -
+
Before OpenACS 3.3, the OpenACS startup process was extremely simple: after AOLserver
performed its internal initialization (reading the configuration file,
loading shared libraries and module code, etc.) it scanned through the Tcl
-library directory (generally /var/lib/aolserver/
yourservername
/tcl
),
+library directory (generally /var/lib/aolserver/yourservername/tcl),
sourcing each file in sequence.
While this overall structure for initialization is still intact, package management has thrown a wrench into the works - there are a few extra things -to do during initialization, most notably:
Examine the OpenACS file tree for files that should not be present in OpenACS +to do during initialization, most notably:
Examine the OpenACS file tree for files that should not be present in OpenACS (i.e., that were once part of the OpenACS distribution but have since been -removed).
Scan the /packages
directory for new packages.
Initialize enabled packages by sourcing their *-procs.tcl
-and *-init.tcl
files.
+removed).
Scan the /packages directory for new packages.
Initialize enabled packages by sourcing their *-procs.tcl +and *-init.tcl files.
This document examines in detail each of the steps involved in AOLserver/OpenACS startup. -
+As soon as the nsd daemon is executed by the init
process (or otherwise), AOLserver reads its configuration file and
-chroot
s itself if necessary. It then loads shared libraries
-indicated in the .ini
file (e.g., the Oracle driver and
-nssock
), and sources Tcl module files (generally in
-/home/aol30/modules/tcl
). This step is, and has always been, the
+chroots itself if necessary. It then loads shared libraries
+indicated in the .ini file (e.g., the Oracle driver and
+nssock), and sources Tcl module files (generally in
+/home/aol30/modules/tcl). This step is, and has always been, the
same for all AOLservers, regardless of whether they are running OpenACS.
Next AOLserver sources, in lexicographical order, each file in the
-/tcl
directory. The first such file is
-0-acs-init.tcl
, which doesn't do much directly except to
-determine the OpenACS path root (e.g., /var/lib/aolserver/
yourservername
)
+/tcl directory. The first such file is
+0-acs-init.tcl, which doesn't do much directly except to
+determine the OpenACS path root (e.g., /var/lib/aolserver/yourservername)
by trimming the final component from the path to the Tcl library directory
-(/var/lib/aolserver/
yourservername
/tcl
). But
-0-acs-init.tcl
's has an important function, namely sourcing
-/packages/acs-core/bootstrap.tcl
, which does the following:
Initialize some NSVs used by the core. These NSVs are
-documented in /packages/acs-core/apm-procs.tcl
- no need to
+(/var/lib/aolserver/yourservername/tcl). But
+0-acs-init.tcl's has an important function, namely sourcing
+/packages/acs-core/bootstrap.tcl, which does the following:
Initialize some NSVs used by the core. These NSVs are +documented in /packages/acs-core/apm-procs.tcl - no need to worry about them unless you're an OpenACS core hacker. -
Verify the deletion of obsolete OpenACS files. The
-/tcl
directory has evolved quite a bit over the months and
+
Verify the deletion of obsolete OpenACS files. The
+/tcl directory has evolved quite a bit over the months and
years, and a few files have come and gone. The
-/www/doc/removed-files.txt
file contains a list of files which
+/www/doc/removed-files.txt file contains a list of files which
must be deleted from the AOLserver installation, at the risk of
causing weird conflicts, e.g., having several security filters registered.
-bootstrap.tcl
scans through this list, logging error messages to
+bootstrap.tcl scans through this list, logging error messages to
the log if any of these files exist.
-
Source *-procs.tcl
files in the OpenACS core.
-We source each file matching the *-procs.tcl
glob in the
-/packages/acs-kernel
directory, in lexicographical order. These
+
Source *-procs.tcl files in the OpenACS core. +We source each file matching the *-procs.tcl glob in the +/packages/acs-kernel directory, in lexicographical order. These procedure are needed to perform any of the following steps. -
Ensure that the database is available by grabbing and +
Ensure that the database is available by grabbing and releasing a handle. If we can't obtain a handle, we terminate initialization (since OpenACS couldn't possibly start up the server without access to the database). -
Register any new packages in the /packages
-directory. In each directory inside /packages
, we look
-for a .info
file; if we find a package that hasn't yet been
+
Register any new packages in the /packages
+directory. In each directory inside /packages, we look
+for a .info file; if we find a package that hasn't yet been
registered with the package manager (i.e., it's been copied there
manually), we insert information about it into the database. (The first time
OpenACS starts up, no packages will have been registered in the database
yet, so this step will registers every single package in the
-/packages
directory.) Note that packages discovered here are
+/packages directory.) Note that packages discovered here are
initially disabled; they must be manually enabled in the package manager
before they can be used.
-
Ensure that the acs-kernel
package is
-enabled. If the OpenACS core isn't initialized, the server
+
Ensure that the acs-kernel package is +enabled. If the OpenACS core isn't initialized, the server couldn't possibly be operational, so if there's no enabled version of the OpenACS core we simply mark the latest installed one as enabled. -
Load *-procs.tcl
files for enabled
-packages, activating their APIs.
+
Load *-procs.tcl files for enabled +packages, activating their APIs. -
Load *-init.tcl
files for enabled packages,
+
Load *-init.tcl files for enabled packages, giving packages a chance to register filters and procedures, initialize data structures, etc. -
Verify that the core has been properly initialized by +
Verify that the core has been properly initialized by checking for the existence of an NSV created by the request processor initialization code. If it's not present, the server won't be operational, so we log an error.
-At this point, bootstrap.tcl
is done executing. AOLserver
-proceeds to source the remaining files in the /tcl
directory
+At this point, bootstrap.tcl is done executing. AOLserver
+proceeds to source the remaining files in the /tcl directory
(i.e., unpackaged libraries) and begins listening for connections.
Prev | Home | Next |
Documenting Tcl Files: Page Contracts and Libraries | Up | External Authentication Requirements |
Prev | Home | Next |
Prerequisite Software | Up | Install a Unix-like system and supporting software |
Prev | Home | Next |
Prerequisite Software | Up | Install a Unix-like system and supporting software |
+
By Joel Aufrecht with input from Jeff Davis, Branimir Dolicki, and Jade Rubick.
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
All OpenACS code is available anonymously. To get code
anonymously, use the parameter
- -d:pserver:anonymous@cvs.openacs.org:/cvsroot
immediately after cvs
in a cvs command to check out or export code.
+ -d:pserver:anonymous@cvs.openacs.org:/cvsroot immediately after cvs in a cvs command to check out or export code.
If you are an OpenACS developer, you should check out code so
that you or any other developer can commit it. To do this, use
the parameter
- -d:ext:cvs.openacs.org:/cvsroot
- immediately after cvs
in
+ -d:ext:cvs.openacs.org:/cvsroot
+ immediately after cvs in
checkout commands. This will create a local checkout directory
that uses cvs.openacs.org but does not specify the user. By
default, it will use your local account name as the user, so if
- you are logged in as "foobar" it will try to check out and
+ you are logged in as "foobar" it will try to check out and
commit as if you had specified
- :ext:foobar@cvs.openacs.org:/cvsroot
. The advantage of not specifying a user in the checkout command is that other users can work in the directory using their own accounts.
+ :ext:foobar@cvs.openacs.org:/cvsroot. The advantage of not specifying a user in the checkout command is that other users can work in the directory using their own accounts.
OpenACS.org supports non-anonymous cvs access only over ssh, so you
- must have CVS_RSH=ssh
in your
+ must have CVS_RSH=ssh in your
environment. (Typically this is accomplished by putting
- export CVS_RSH=ssh
into
- ~/.bash_profile
.). If your local
+ export CVS_RSH=ssh into
+ ~/.bash_profile.). If your local
account name does not match your cvs.openacs.org account name, create a
- file ~/.ssh/config
with an entry
+ file ~/.ssh/config with an entry
like:
Host cvs.openacs.org User joel
With this setup, you will be asked for your password with each cvs command. To avoid this, set up ssh certificate - authentication for your openacs account. (More + authentication for your openacs account. (More information)
You may want to set some more default actions for CVS usage.
To do so, create the file
- ~/.cvsrc
with the contents:
+ ~/.cvsrc with the contents:
cvs -z6
-cvs -q
-z6
speeds up cvs access over the network quite a bit by enabling compressed
- connection by default. -q
suppresses some verbose output from commands. For example, it makes the output of cvs up
much easier to read.
Administrator Note: These are the steps to grant CVS commit rights to a user:
Create the user's account. On cvs.openacs.org:
sudo bash
-/usr/sbin/useradd -c "Real Name" -G cvs -p passwd username
+cvs -q
-z6 speeds up cvs access over the network quite a bit by enabling compressed + connection by default. -q suppresses some verbose output from commands. For example, it makes the output of cvs up much easier to read.
Administrator Note: These are the steps to grant CVS commit rights to a user:
Create the user's account. On cvs.openacs.org:
sudo bash
+/usr/sbin/useradd -c "Real Name" -G cvs -p passwd username
/usr/sbin/usermod -G cvs,username username
-
Grant cvs access to the user account. On any machine, in a temporary directory:
cvs -d :ext:cvs.openacs.org:/cvsroot co CVSROOT
+
Grant cvs access to the user account. On any machine, in a temporary directory:
cvs -d :ext:cvs.openacs.org:/cvsroot co CVSROOT
cd CVSROOT
-emacs avail
Add an avail line of the form:
avail|username|openacs-4
cvs commit -m "added commit on X for username" avail
Branimir suggests an additional level of abstraction. If you put
Host cvs-server +emacs avail
Add an avail line of the form:
avail|username|openacs-4
cvs commit -m "added commit on X for username" avail
Branimir suggests an additional level of abstraction. If you put
Host cvs-server
HostName cvs.openacs.org
- User yournamehere
into your ~/.ssh/config
file, then you can use -d :ext:cvs-server:/cvsroot
instead of -d :ext:cvs.openacs.org:/cvsroot
. You can then change the definition of cvs-server
by changing one file instead of editing hundreds of CVSROOT/Repository
files.
If you are actively developing a non-core package, you + User yournamehere
into your ~/.ssh/config file, then you can use -d :ext:cvs-server:/cvsroot instead of -d :ext:cvs.openacs.org:/cvsroot. You can then change the definition of cvs-server by changing one file instead of editing hundreds of CVSROOT/Repository files.
If you are actively developing a non-core package, you should work from the latest core release branch. Currently this is oacs-5-6. This ensures that you are working on top of a stable OpenACS core, but still allows you to commit feature @@ -62,34 +64,34 @@ want to use only acs-core plus some specific modules. To do this, check out core first:
cvs -d:ext:cvs.openacs.org:/cvsroot -r oacs-5-6 checkout acs-core
Then add modules as needed:
cd /var/lib/aolserver/service0/packages
cvs up -d packagename
... where packagename is the - name of the package you want. Visit the Package - Inventory and Package + name of the package you want. Visit the Package + Inventory and Package maintainers and status for a list of available packages and their current state. -
If you are actively developing packages in the OpenACS
Core, work from the HEAD branch. HEAD is used for active
development of the next version of core OpenACS. It may be very
buggy; it may not even install correctly. Do not use this branch for
development of non-core features unless your work depends on some
of the HEAD core work. To check out HEAD, omit the
- -r
tag.
To check out HEAD for development, which requires an OpenACS developer account:
cvs -d:ext:cvs.openacs.org:/cvsroot checkout acs-core
To check out HEAD anonymously:
cvs -d:pserver:anonymous@cvs.openacs.org:/cvsroot checkout acs-core
+ -r tag.
To check out HEAD for development, which requires an OpenACS developer account:
cvs -d:ext:cvs.openacs.org:/cvsroot checkout acs-core
To check out HEAD anonymously:
cvs -d:pserver:anonymous@cvs.openacs.org:/cvsroot checkout acs-core
.LRN consists of a given version openacs core, plus a set of
packages. These are collectively packages together to form a
distrubution of .LRN. F .LRN 2.0.0 sits on top of OpenACS 5.0.0.
.LRN also uses an OpenACS install.xml file during installation;
this file is distributed within the dotlrn package and must be
moved. To get a development checkout of .LRN in the subdirectory
- dotlrn
:
+ dotlrn:
cvs -d :pserver:anonymous@cvs.openacs.org:/cvsroot checkout -r oacs-5-6 acs-core
mv openacs-4 dotlrn
cd dotlrn/packages
cvs -d :pserver:anonymous@cvs.openacs.org:/cvsroot checkout -r oacs-5-6 dotlrn-all
-mv dotlrn/install.xml ..
Once you have a checkout you can use some commands to track
- what has changed since you checked out your copy. cvs -n update
does not change any files, but reports which changes have been updated or locally modified, or are not present in CVS.
-
To update your files, use cvs update
. This will merge changes from the repository with your local files. It has no effect on the cvs.openacs.org repository.
- All OpenACS code resides within a single CVS module, openacs-4
. (The openacs-4 directory contains code for all versions of OpenACS 4 and later, and .LRN 1 and later.) Checking out this module retrieves all openacs code of any type. For convenience, subsets of openacs-4
are repackaged as smaller modules.
- acs-core
contains only critical common
+ what has changed since you checked out your copy. cvs -n update does not change any files, but reports which changes have been updated or locally modified, or are not present in CVS.
+
To update your files, use cvs update. This will merge changes from the repository with your local files. It has no effect on the cvs.openacs.org repository.
+ All OpenACS code resides within a single CVS module, openacs-4. (The openacs-4 directory contains code for all versions of OpenACS 4 and later, and .LRN 1 and later.) Checking out this module retrieves all openacs code of any type. For convenience, subsets of openacs-4 are repackaged as smaller modules.
+ acs-core contains only critical common packages. It does not have any user applications, such as forums, bug-tracker, calendar, or ecommerce. These can be added at any time. @@ -110,29 +112,29 @@ acs-tcl acs-templating ref-timezones search
- dotlrn-all
contains the packages required, in combination with acs-core, to run the .LRN system.
+ dotlrn-all contains the packages required, in combination with acs-core, to run the .LRN system.
- project-manager-all
contains the packages required, in combination with acs-core, to run the project-manager package.
+ project-manager-all contains the packages required, in combination with acs-core, to run the project-manager package.
- Each OpenACS package (i.e., directory in openacs-4/packages/
) is also aliased as a module of the same name.
-
Tags and Branches look similar in commands, but behave differently. A tag is a fixed point on a branch. Check out a tag to get a specific version of OpenACS. Check out a branch to get the most current code for that major-minor version (e.g., 5.0.x or 5.1.x). You can only commit to a branch, not a tag, so check out - a branch if you will be working on the code.
openacs-x-y-z-final
- tags mark final releases of OpenACS. This tag is applied to the acs-core files for an OpenACS core release, and to the latest released versions of all other packages at the time of release. Example: openacs-5-0-4-final
.
-
dotlrn-x-y-z-final
- tags mark final releases of .LRN. These tags apply only to .LRN packages. Example: dotlrn-2-0-1-final
-
packagename-x-y-z-final
- tags apply to releases of individual packages. For example, calendar-2-0-0-final
is a tag that will retrieve only the files in the calendar 2.0.0 release. It applies only to the
+ a branch if you will be working on the code.
openacs-x-y-z-final + tags mark final releases of OpenACS. This tag is applied to the acs-core files for an OpenACS core release, and to the latest released versions of all other packages at the time of release. Example: openacs-5-0-4-final. +
dotlrn-x-y-z-final + tags mark final releases of .LRN. These tags apply only to .LRN packages. Example: dotlrn-2-0-1-final +
packagename-x-y-z-final + tags apply to releases of individual packages. For example, calendar-2-0-0-final is a tag that will retrieve only the files in the calendar 2.0.0 release. It applies only to the calendar package. All non-core, non-dotlrn packages should have a tag of this style, based on the package name. Many packages have not been re-released since the new naming convention was adopted and so don't have a tag of this type. -
openacs-x-y-compat
tags point to the most recent released version of OpenACS X.Y.
+
openacs-x-y-compat tags point to the most recent released version of OpenACS X.Y. It is similar to openacs-x-y-z-compat, except that it will always get the most recent dot-release of Core and the most recent compatible, released version of all other @@ -146,51 +148,51 @@ package, etc. If you update the checkout two months later, you might get version 5.0.5 of all OpenACS core packages and version 2.1 of calendar. -
oacs-x-y is a branch, , not a tag. All core packages in the 5.0 release series (5.0.0, 5.0.1, 5.0.2, etc) are also on the oacs-5-0 branch. Similarly, OpenACS core packages for 5.1.0 are on the oacs-5-1 branch.
These branches are used for two purposes. OpenACS +
oacs-x-y is a branch, , not a tag. All core packages in the 5.0 release series (5.0.0, 5.0.1, 5.0.2, etc) are also on the oacs-5-0 branch. Similarly, OpenACS core packages for 5.1.0 are on the oacs-5-1 branch.
These branches are used for two purposes. OpenACS Core packages on these branches are being tidied up for release. Only bug fixes, not new features, should be added to core packages on release branches. For all other packages, release branches are the recommended location for development. For example, if you are working on calendar, which is compatible with openacs 5.0 but not - 5.1, work on the oacs-5-0 branch.
HEAD
is a branch used
- for development of core packages.
There are three main ways to contribute code to OpenACS:
To contribute a small fix, if you do not have a developer account, submit a patch.
If you are making many changes, or would like to become a direct contributor, send mail to the Core Team asking for commit rights. You can then commit code directly to the repository:
Use one of the checkout methods described above to get files to your system. This takes the place of steps 1 and 2 in Installation Option 2: Install from tarball. Continue setting up the site as described there.
Fix bugs and add features.
- Commit that file (or files):
cvs commit -m "what I did and why" filename
+ 5.1, work on the oacs-5-0 branch.
HEAD is a branch used + for development of core packages.
There are three main ways to contribute code to OpenACS:
To contribute a small fix, if you do not have a developer account, submit a patch.
If you are making many changes, or would like to become a direct contributor, send mail to the Core Team asking for commit rights. You can then commit code directly to the repository:
Use one of the checkout methods described above to get files to your system. This takes the place of steps 1 and 2 in Section , “Installation Option 2: Install from tarball”. Continue setting up the site as described there.
Fix bugs and add features.
+ Commit that file (or files):
cvs commit -m "what I did and why" filename
Because this occurs in your personal checkout and not an anonymous one, this commit automagically moves back upstream to the Mother Ship repository at cvs.openacs.org. The names of the changed files, and your comments, are sent to a mailing list for OpenACS developers. A Core Team developer may review or roll back your changes if necessary. -
- Confirm via the +
+ Confirm via the OpenACS CVS browser that your changes are where you intended them to be. -
Add a new package. Contact the Core Team to get approval and to get a module alias created.
+
Add a new package. Contact the Core Team to get approval and to get a module alias created.
Check out acs-core on the HEAD branch. (Weird things happen if you add files to a branch but not to HEAD):
cd /tmp
cvs -d:ext:cvs.openacs.org:/cvsroot checkout acs-core
Copy your package directory from your working directory to this directory. Make sure not to copy any CVS directories.
cp -r /var/lib/aolserver/service0/packages/newpackage /tmp/openacs-4/packages
Import the package into the cvs.openacs.org cvs repository:
cd /tmp/openacs-4/packages/newpackage
-cvs import -m "Initial import of newpackage" openacs-4/packages/newpackage myname newpackage-0-1d
Add the new package to the modules file. (An administrator has to do this step.) On any machine, in a temporary directory:
cvs -d :ext:cvs.openacs.org:/cvsroot co CVSROOT
+cvs import -m "Initial import of newpackage" openacs-4/packages/newpackage myname newpackage-0-1d
Add the new package to the modules file. (An administrator has to do this step.) On any machine, in a temporary directory:
cvs -d :ext:cvs.openacs.org:/cvsroot co CVSROOT
cd CVSROOT
-emacs modules
Add a line of the form:
photo-album-portlet openacs-4/packages/photo-album-portlet
Commit the change:
cvs commit -m "added alias for package newpackage" modules
This should print something like:
cvs commit: Examining .
+emacs modules
Add a line of the form:
photo-album-portlet openacs-4/packages/photo-album-portlet
Commit the change:
cvs commit -m "added alias for package newpackage" modules
This should print something like:
cvs commit: Examining .
**** Access allowed: Personal Karma exceeds Environmental Karma.
Checking in modules;
/cvsroot/CVSROOT/modules,v <-- modules
new revision: 1.94; previous revision: 1.93
done
-cvs commit: Rebuilding administrative file database
Although you should add your package on HEAD, you should do package development on the latest release branch that your code is compatible with. So, after completing the import, you may want to branch your package:
cd /var/lib/aolserver/service0/packages/newpackage -cvs tag -b oacs-5-1
Some packages are already in cvs at openacs-4/contrib/packages
. Starting with OpenACS 5.1, we have a Maturity mechanism in the APM which makes the contrib
directory un-necessary. If you are working on a contrib
package, you should move it to /packages
. This must be done by an OpenACS administrator. On cvs.openacs.org:
cp -r /cvsroot/openacs-4/contrib/packages/package0 /cvsroot/openacs-4/packages
Update the modules file as described above.
Remove the directory from cvs in the old location using cvs rm
. One approach for file in `find | grep -v CVS`; do rm $file; cvs remove $file; done
Although you should add your package on HEAD, you should do package development on the latest release branch that your code is compatible with. So, after completing the import, you may want to branch your package:
cd /var/lib/aolserver/service0/packages/newpackage +cvs tag -b oacs-5-1
See Section , “How to package and release an OpenACS Package”
Some packages are already in cvs at openacs-4/contrib/packages. Starting with OpenACS 5.1, we have a Maturity mechanism in the APM which makes the contrib directory un-necessary. If you are working on a contrib package, you should move it to /packages. This must be done by an OpenACS administrator. On cvs.openacs.org:
cp -r /cvsroot/openacs-4/contrib/packages/package0 /cvsroot/openacs-4/packages
Update the modules file as described above.
Remove the directory from cvs in the old location using cvs rm. One approach for file in `find | grep -v CVS`; do rm $file; cvs remove $file; done
CVS commit procedures are governed by - + TIP (Technical Improvement Proposal) #61: Guidelines for CVS committers -
+
Which branch? -
+
For core packages, new features should always be committed on HEAD, not to release branches. -
+
For core packages, bug fixes should be committed on the current release branch whenever applicable. -
+
For non-core packages, developers should work on a checkout of the release branch of the lastest release. For example, if OpenACS 5.1.0 is released, developers should work on the @@ -199,27 +201,27 @@ released.
- Reason: First, this ensures that developers are working against stable core code. Second, it ensures that new package releases are available to OpenACS users immediately.
+ Reason: First, this ensures that developers are working against stable core code. Second, it ensures that new package releases are available to OpenACS users immediately.
The current release branch is merged back to HEAD after each dot release. -
+
New packages should be created in the
-
+
/packages
-
+
directory
and the maturity flag in the .info file should be zero. This is a change from
previous policy, where new packages went to /contrib/packages)
-
+
Code -
+
Only GPL code and material should be committed to the OpenACS CVS repository (cvs.openacs.org) -
Do not mix formatting changes with code changes. Instead, make a formatting-only change which does not affect the logic, and say so in the commit comment. Then, make the logic change in a separate commit. Reason: This makes auditing and merging code much easier. -
+
Do not mix formatting changes with code changes. Instead, make a formatting-only change which does not affect the logic, and say so in the commit comment. Then, make the logic change in a separate commit. Reason: This makes auditing and merging code much easier. +
Database upgrade scripts should only span one release increment, and should follow - + Naming Database Upgrade Scripts . @@ -232,57 +234,57 @@ that using rc1 instead of b1 would be nice, because that's the convention with release codes in cvs, but the package manager doesn't support rc tags. -
+
Database upgrade scripts should never go to the release version, e.g., should always have a letter suffix such as d1 or b1. -
+
CVS commit messages should be intelligible in the context of Changelogs. They should not refer to the files or versions. -
+
CVS commit messages and code comments should refer to - bug, tip, or patch number if appropriate, in the format "resolves - bug 11", "resolves bugs 11, resolves bug 22". "implements tip 42", - "implements tip 42, implements tip 50", "applies patch 456 by User - Name", "applies patch 456 by User Name, applies patch 523 by - ...". -
+ bug, tip, or patch number if appropriate, in the format "resolves + bug 11", "resolves bugs 11, resolves bug 22". "implements tip 42", + "implements tip 42, implements tip 50", "applies patch 456 by User + Name", "applies patch 456 by User Name, applies patch 523 by + ...". +
When to TIP -
+
A TIP is a Techical Improvement Proposal ( - + more information ). A proposed change must be approved by TIP if: -
+
It changes the core data model, or -
+
It will change the behavior of any core package in a way that affects existing code (typically, by changing public API), or -
+
It is a non-backwards-compatible change to any core or standard package. -
+
A proposed change need not be TIPped if: -
+
it adds a new function to a core package in a way that: -
+
does not change the backwards-compatibility of public API functions. -
+
does not change the data model -
+
has no negative impact on performance -
+
it changes private API, or -
+
it is a change to a non-core, non-standard package -
+
Tags -
+
When a package is released in final form, the developer - shall tag it "packagename-x-y-z-final" and "openacs-x-y-compat". x-y + shall tag it "packagename-x-y-z-final" and "openacs-x-y-compat". x-y should correspond to the current branch. If the package is compatible with several different core versions, several compat tags should be applied. @@ -297,7 +299,7 @@ identify packages which have been released since the last core release.Reason 3: The compat tag or something similar is required to make Rule 6 possible. -
+
When OpenACS core is released, the openacs-x-y-z-final tag shall be applied to all compat packages.
@@ -315,110 +317,110 @@ flag which defaults to no-effect wouldn't require a TIP. Added a new mandatory flag to an existing function would require a TIP. -
Informal guidelines which may be obsolete in places and should be reviewed: -
+
Before committing to cvs you must submit a bug report and patch to the - + OpenACS bug tracker . The only exceptions to this rule are for - + package maintainers committing in a package they are maintaining and for members of the core team. -
+
If you are committing a bug fix you need to coordinate with the package maintainer. If you are a maintainer then coordinate with any fellow maintainers. -
+
If you are to commit a new feature, an architecture change, or a refactoring, you must coordinate with the OpenACS core team first. Also, such changes should have a discussion in the forums to allow for feedback from the whole community. -
+
If you are changing the data model you *must* provide an upgrade script and bump up the version number of the package. -
+
Consider any upgradability ramifications of your change. Avoid changing the contract and behaviour of Tcl procedures. If you want to build a new and clean API consider deprecating the old proc and making it invoke the new one. -
+
Never rush to commit something. Before committing double check with cvs diff what exactly you are committing. -
+
Always accompany a commit with a brief but informative comment. If your commit is related to bug number N and/or patch - number P, indicate this in the commit comment by including "bug N" - and/or "patch P". This allows us to link bugs and patches in the + number P, indicate this in the commit comment by including "bug N" + and/or "patch P". This allows us to link bugs and patches in the Bug Tracker with changes to the source code. For example suppose you are committing a patch that closes a missing HTML tag, then an - appropriate comment could be "Fixing bug 321 by applying patch 134. - Added missing h3 HTML close tag". -
+ appropriate comment could be "Fixing bug 321 by applying patch 134. + Added missing h3 HTML close tag". +
Commit one cohesive bug fix or feature change at a time. Don't put a bunch of unrelated changes into one commit. -
+
Before you throw out or change a piece of code that you don't fully understand, use cvs annotate and cvs log on the file to see who wrote the code and why. Consider contacting the author. -
+
Test your change before committing. Use the OpenACS package acs-automated-testing to test Tcl procedures and the tool - + Tclwebtest to test pages -
+
Keep code simple, adhere to conventions, and use comments liberally. -
+
In general, treat the code with respect, at the same time, never stop questioning what you see. The code can always be improved, just make sure you change the code in a careful and systematic fashion. -
The - + OpenACS cvs web and - + Jeff's cvs browser are useful tools in understanding what is happening with the code. -
+
There is a mailing list of cvs changes at - + willfork.com -
There is an RSS feed of cvs changes at - +
There is an RSS feed of cvs changes at + RSS feed -
- cvs manual -
- backup with cvs -
+ cvs manual +
+ backup with cvs +
Table of Contents
Table of Contents
Prev | Home | Next |
Diagnosing Performance Problems | Up | Running a PostgreSQL database on another server |
By Jon Salz. Revised and expanded by Roberto Mello (rmello at fslc dot usu dot edu), July 2002.
+ +By Jon Salz. Revised and expanded by Roberto Mello (rmello at fslc dot usu dot edu), July 2002.
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Tcl procedures: /packages/acs-kernel/10-database-procs.tcl
Tcl initialization: /packages/acs-kernel/database-init.tcl
Tcl procedures: /packages/acs-kernel/10-database-procs.tcl
Tcl initialization: /packages/acs-kernel/database-init.tcl
One of OpenACS's great strengths is that code written for it is very close to the database. It is very easy to interact with the database from anywhere within OpenACS. Our goal is to develop a coherent API for database access which makes this even easier.
There were four significant problems with the way OpenACS previously used the
-database (i.e., directly through the ns_db
interface):
Handle management. We required code to pass database +database (i.e., directly through the ns_db interface):
Handle management. We required code to pass database handles around, and for routines which needed to perform database access but didn't receive a database handle as input, it was difficult to know from -which of the three "magic pools" (main, subquery, and log) to +which of the three "magic pools" (main, subquery, and log) to allocate a new handle. -
Nested transactions. In our Oracle driver, begin
-transaction
really means "turn auto-commit mode off" and
-end transaction
means "commit the current transaction and
-turn auto-commit mode on." Thus if transactional code needed to call a
+
Nested transactions. In our Oracle driver, begin +transaction really means "turn auto-commit mode off" and +end transaction means "commit the current transaction and +turn auto-commit mode on." Thus if transactional code needed to call a routine which needed to operate transactionally, the semantics were non-obvious. Consider:
@@ -29,47 +29,47 @@ } db_transaction { -db_dml unused "insert into greeble(bork) values(33)" +db_dml unused "insert into greeble(bork) values(33)" foo $db -db_dml unused "insert into greeble(bork) values(50)" +db_dml unused "insert into greeble(bork) values(50)" }
-This would insert greeble #33 and do all the stuff in foo
-transactionally, but the end transaction
in foo
+This would insert greeble #33 and do all the stuff in foo
+transactionally, but the end transaction in foo
would actually cause a commit, and greeble #50 would later be inserted in
auto-commit mode. This could cause subtle bugs: e.g., in the case that the
-insert for greeble #50 failed, part of the "transaction" would have
+insert for greeble #50 failed, part of the "transaction" would have
already have been committed!. This is not a good thing.
-
Unorthodox use of variables. The standard mechanism for +
Unorthodox use of variables. The standard mechanism for
mapping column values into variables involved the use of the
-set_variables_after_query
routine, which relies on an uplevel
-variable named selection
(likewise for
-set_variables_after_subquery
and subselection
).
+set_variables_after_query routine, which relies on an uplevel
+variable named selection (likewise for
+set_variables_after_subquery and subselection).
-
Hard-coded reliance on Oracle. It's difficult to +
Hard-coded reliance on Oracle. It's difficult to
write code supporting various different databases (dynamically using the
appropriate dialect based on the type of database being used, e.g., using
-DECODE
on Oracle and CASE ... WHEN
on
+DECODE on Oracle and CASE ... WHEN on
Postgres).
The Database Access API addresses the first three problems by: -
making use of database handles transparent
wrapping common database operations (including transaction management) in +
making use of database handles transparent
wrapping common database operations (including transaction management) in Tcl control structures (this is, after all, what Tcl is good at!)
It lays the groundwork for addressing the fourth problem by assigning each SQL statement a logical name. In a future version of the OpenACS Core, this API will translate logical statement names into actual SQL, based on the type of database in use. (To smooth the learning curve, we provide a facility for -writing SQL inline for a "default SQL dialect", which we assume to +writing SQL inline for a "default SQL dialect", which we assume to be Oracle for now.)
To be clear, SQL abstraction is not fully implemented in OpenACS 3.3.1. The statement names supplied to each call are not used by the API at all. The API's design for SQL abstraction is in fact incomplete; -unresolved issues include:
how to add WHERE
clause criteria dynamically
how to build a dynamic ORDER BY
clause (Ben Adida has a
-proposed solution for this)
how to define a statement's formal interface (i.e., what bind
-variables it expects, what columns its SELECT
clause must
+unresolved issues include:
how to add WHERE clause criteria dynamically
how to build a dynamic ORDER BY clause (Ben Adida has a +proposed solution for this)
how to define a statement's formal interface (i.e., what bind +variables it expects, what columns its SELECT clause must contain if it's a query) without actually implementing the statement in a specific SQL dialect
So why is the incremental change of adding statement naming to the API worth @@ -78,81 +78,81 @@ design. Therefore, we know that the effort will not be wasted, and taking advantage of the new support for bind variables will already require code that uses 3.3.0 version of the API to be updated. -
-set_variables_after_query
is gone! (Well, it's still there,
+
+set_variables_after_query is gone! (Well, it's still there, but you'll never need to use it.) The new API routines set local variables automatically. For instance:
-db_1row select_names "select first_names, last_name from users where user_id = [ad_get_user_id]" -doc_body_append "Hello, $first_names $last_name!" +db_1row select_names "select first_names, last_name from users where user_id = [ad_get_user_id]" +doc_body_append "Hello, $first_names $last_name!"
-Like ns_db 1row
, this will bomb if the query doesn't return
+Like ns_db 1row, this will bomb if the query doesn't return
any rows (no such user exists). If this isn't what you want, you can
write:
-if { [db_0or1row select_names "select first_names, last_name from users where user_id = [ad_get_user_id]"] } { - doc_body_append "Hello, $first_names $last_name!" +if { [db_0or1row select_names "select first_names, last_name from users where user_id = [ad_get_user_id]"] } { + doc_body_append "Hello, $first_names $last_name!" } else { # Executed if the query returns no rows. - doc_body_append "There's no such user!" + doc_body_append "There's no such user!" }
Selecting a bunch of rows is a lot prettier now:
-db_foreach select_names "select first_names, last_name from users" { - doc_body_append "Say hi to $first_names $last_name for me!<br>" +db_foreach select_names "select first_names, last_name from users" { + doc_body_append "Say hi to $first_names $last_name for me!<br>" }
-That's right, db_foreach
is now like ns_db
-select
plus a while
loop plus
-set_variables_after_query
plus an if
statement
+That's right, db_foreach is now like ns_db
+select plus a while loop plus
+set_variables_after_query plus an if statement
(containing code to be executed if no rows are returned).
-db_foreach select_names "select first_names, last_name from users where last_name like 'S%'" { - doc_body_append "Say hi to $first_names $last_name for me!<br>" +db_foreach select_names "select first_names, last_name from users where last_name like 'S%'" { + doc_body_append "Say hi to $first_names $last_name for me!<br>" } if_no_rows { - doc_body_append "There aren't any users with last names beginnings with S!" + doc_body_append "There aren't any users with last names beginnings with S!" } -
The new API keeps track of which handles are in use, and automatically allocates new handles when they are necessary (e.g., to perform subqueries while a select is active). For example:
-doc_body_append "<ul>" -db_foreach select_names "select first_names, last_name, user_id from users" { +doc_body_append "<ul>" +db_foreach select_names "select first_names, last_name, user_id from users" { # Automatically allocated a database handle from the main pool. - doc_body_append "<li>User $first_names $last_name\n<ul>" + doc_body_append "<li>User $first_names $last_name\n<ul>" - db_foreach select_groups "select group_id from user_group_map where user_id = $user_id" { + db_foreach select_groups "select group_id from user_group_map where user_id = $user_id" { # There's a selection in progress, so we allocated a database handle # from the subquery pool for this selection. - doc_body_append "<li>Member of group #$group_id.\n" + doc_body_append "<li>Member of group #$group_id.\n" } if_no_rows { # Not a member of any groups. - doc_body_append "<li>Not a member of any group.\n" + doc_body_append "<li>Not a member of any group.\n" } } -doc_body_append "</ul>" +doc_body_append "</ul>" db_release_unused_handles
A new handle isn't actually allocated and released for every selection,
of course - as a performance optimization, the API keeps old handles around
-until db_release_unused_handles
is invoked (or the script
+until db_release_unused_handles is invoked (or the script
terminates).
-
Note that there is no analogue to ns_db gethandle
- the
-handle is always automatically allocated the first time it's needed.
Introduction
+
Note that there is no analogue to ns_db gethandle - the +handle is always automatically allocated the first time it's needed.
Introduction
Most SQL statements require that the code invoking the statement pass along data associated with that statement, usually obtained from the user. For instance, in order to delete a WimpyPoint presentation, a Tcl script might @@ -162,10 +162,10 @@ delete from wp_presentations where presentation_id = some_presentation_id
-where some_presentation_id
is a number which is a valid
+where some_presentation_id is a number which is a valid
presentation ID of the presentation I want to delete. It's easy to write
code handling situations like this since SQL statements can include
-bind variables, which represent placeholders for actual
+bind variables, which represent placeholders for actual
data. A bind variable is specified as a colon followed by an identifier, so
the statement above can be coded as:
@@ -176,43 +176,43 @@
When this SQL statement is invoked, the value for the bind variable
-:some_presentation_id
is pulled from the Tcl variable
-$some_presentation_id
(in the caller's environment). Note
+:some_presentation_id is pulled from the Tcl variable
+$some_presentation_id (in the caller's environment). Note
that bind variables are not limited to one per statement; you can use an
arbitrary number, and each will pull from the correspondingly named Tcl
-variable. (Alternatively, you can also specify an list or ns_set
+variable. (Alternatively, you can also specify an list or ns_set
providing bind variables' values; see Usage.)
The value of a bind variable is taken literally by the database driver, so
there is never any need to put single-quotes around the value for a bind
-variable, or to use db_quote
to escape single-quotes contained
+variable, or to use db_quote to escape single-quotes contained
in the value. The following works fine, despite the apostrophe:
-set exclamation "That's all, folks!" +set exclamation "That's all, folks!" db_dml exclamation_insert { insert into exclamations(exclamation) values(:exclamation) }
Note that you can use a bind variable in a SQL statement only where you
could use a literal (a number or single-quoted string). Bind variables cannot
be placeholders for things like SQL keywords, table names, or column names,
-so the following will not work, even if $table_name
is set
+so the following will not work, even if $table_name is set
properly:
select * from :table_name -
Why Bind Variables Are Useful
+
Why Bind Variables Are Useful
Why bother with bind variables at all - why not just write the Tcl statement above like this:
-db_dml presentation_delete " +db_dml presentation_delete " delete from wp_presentations where presentation_id = $some_presentation_id -" +"
(Note the use of double-quotes to allow the variable reference to
-$some_presentation_id
to be interpolated in.) This will work,
+$some_presentation_id to be interpolated in.) This will work,
but consider the case where some devious user causes
-some_presentation_id
to be set to something like '3 or
-1 = 1'
, which would result in the following statement being
+some_presentation_id to be set to something like '3 or
+1 = 1', which would result in the following statement being
executed:
@@ -222,24 +222,24 @@ This deletes every presentation in the database! Using bind variables eliminates this gaping security hole: since bind variable values are taken literally. Oracle will attempt to delete presentations whose presentation ID -is literally'3 or 1 = 1'
(i.e., no presentations, since -'3 or 1 = 1'
can't possibly be a valid integer -primary key forwp_presentations
. In general, since Oracle +is literally '3 or 1 = 1' (i.e., no presentations, since +'3 or 1 = 1' can't possibly be a valid integer +primary key for wp_presentations. In general, since Oracle always considers the values of bind variables to be literals, it becomes more difficult for users to perform URL surgery to trick scripts into running dangerous queries and DML. -Usage
Every
db_*
command accepting a SQL command as an argument -supports bind variables. You can either
specify the
-bind
switch to provide a set with bind variable -values, orspecify the
-bind
switch to explicitly provide a list of -bind variable names and values, ornot specify a bind variable list at all, in which case Tcl variables are +
Usage
Every db_* command accepting a SQL command as an argument +supports bind variables. You can either
specify the -bind switch to provide a set with bind variable +values, or
specify the -bind switch to explicitly provide a list of +bind variable names and values, or
not specify a bind variable list at all, in which case Tcl variables are used as bind variables.
-The default behavior (i.e., if the
-bind
switch is omitted) is +The default behavior (i.e., if the -bind switch is omitted) is that these procedures expect to find local variables that correspond in name to the referenced bind variables, e.g.:set user_id 123456 -set role "administrator" +set role "administrator" db_foreach user_group_memberships_by_role { select g.group_id, g.group_name @@ -249,18 +249,18 @@ and map.role = :role } { # do something for each group of which user 123456 is in the role - # of "administrator" + # of "administrator" }-The value of the local Tcl variable
user_id
(123456) is bound to -theuser_id
bind variable. -The
-bind
switch can takes the name of anns_set
+The value of the local Tcl variable user_id (123456) is bound to +the user_id bind variable. +The -bind switch can takes the name of an ns_set containing keys for each bind variable named in the query, e.g.:
set bind_vars [ns_set create] ns_set put $bind_vars user_id 123456 -ns_set put $bind_vars role "administrator" +ns_set put $bind_vars role "administrator" db_foreach user_group_memberships_by_role { select g.group_id, g.group_name @@ -270,11 +270,11 @@ and map.role = :role } -bind $bind_vars { # do something for each group in which user 123456 has the role - # of "administrator" + # of "administrator" }-Alternatively, as an argument to
-bind
you can specify a list of +Alternatively, as an argument to -bind you can specify a list of alternating name/value pairs for bind variables:@@ -284,22 +284,22 @@ where g.group_id = map.user_id and map.user_id = :user_id and map.role = :role -} -bind [list user_id 123456 role "administrator"] { +} -bind [list user_id 123456 role "administrator"] { # do something for each group in which user 123456 has the role - # of "administrator" + # of "administrator" } -+
When processing a DML statement, Oracle coerces empty strings into -
null
. (This coercion does not occur in the -WHERE
clause of a query, i.e. -col = ''
and -col is null
are not equivalent.) +null. (This coercion does not occur in the +WHERE clause of a query, i.e. +col = '' and +col is null are not equivalent.)As a result, when using bind variables, the only way to make Oracle set a -column value to
null
is to set the corresponding bind variable +column value to null is to set the corresponding bind variable to the empty string, since a bind variable whose value is the string -"null" will be interpreted as the literal string -"null".These Oracle quirks complicate the process of writing clear and abstract +"null" will be interpreted as the literal string +"null".
These Oracle quirks complicate the process of writing clear and abstract DML difficult. Here is an example that illustrates why:
# @@ -311,259 +311,259 @@ # ); # -set bar "" -set baz "" +set bar "" +set baz "" -db_dml foo_create "insert into foo(bar, baz) values(:bar, :baz)" +db_dml foo_create "insert into foo(bar, baz) values(:bar, :baz)" # -# the values of the "bar" and "baz" columns in the new row are both +# the values of the "bar" and "baz" columns in the new row are both # null, because Oracle has coerced the empty string (even for the -# numeric column "bar") into null in both cases +# numeric column "bar") into null in both casesSince databases other than Oracle do not coerce empty strings into -
null
, this code has different semantics depending on the +null, this code has different semantics depending on the underlying database (i.e., the row that gets inserted may not have null as its column values), which defeats the purpose of SQL abstraction.Therefore, the Database Access API provides a database-independent way to -represent
null
(instead of the Oracle-specific idiom of the -empty string):db_null
.Use it instead of the empty string whenever you want to set a column value -explicitly to
null
, e.g.:+represent null (instead of the Oracle-specific idiom of the +empty string): db_null.Use it instead of the empty string whenever you want to set a column value +explicitly to null, e.g.:
set bar [db_null] set baz [db_null] -db_dml foo_create "insert into foo(bar, baz) values(:bar, :baz)" +db_dml foo_create "insert into foo(bar, baz) values(:bar, :baz)" # -# sets the values for both the "bar" and "baz" columns to null +# sets the values for both the "bar" and "baz" columns to null -We now require that each SQL statement be assigned a logical name for the statement that is unique to the procedure or page in which it is defined. This is so that (eventually) we can implement logically named statements with alternative SQL for non-Oracle databases (e.g., Postgres). More on this later. -
-Normally,
db_foreach
,db_0or1row
, and -db_1row
places the results of queries in Tcl variables, so you ++Normally, db_foreach, db_0or1row, and +db_1row places the results of queries in Tcl variables, so you can say:
-db_foreach users_select "select first_names, last_name from users" { - doc_body_append "<li>$first_names $last_name\n" +db_foreach users_select "select first_names, last_name from users" { + doc_body_append "<li>$first_names $last_name\n" }However, sometimes this is not sufficient: you may need to examine the rows returned, to dynamically determine the set of columns returned by the query, or to avoid collisions with existing variables. You can use the -
-column_array
and-column_set
switches to -db_foreach
,db_0or1row
, anddb_1row
to +-column_array and -column_set switches to +db_foreach, db_0or1row, and db_1row to instruct the database routines to place the results in a Tcl array or -ns_set
, respectively, where the keys are the column names and +ns_set, respectively, where the keys are the column names and the values are the column values. For example:-db_foreach users_select "select first_names, last_name from users" -column_set columns { +db_foreach users_select "select first_names, last_name from users" -column_set columns { # Now $columns is an ns_set. - doc_body_append "<li>" + doc_body_append "<li>" for { set i 0 } { $i < [ns_set size $columns] } { incr i } { - doc_body_append "[ns_set key $columns $i] is [ns_set value $columns $i]. \n" + doc_body_append "[ns_set key $columns $i] is [ns_set value $columns $i]. \n" } }will write something like: -
first_names is Jon. last_name is Salz.
first_names is Lars. last_name is Pind.
first_names is Michael. last_name is Yoon.
-Note that you never have to use
ns_db
anymore (including -ns_db gethandle
)! Just start doing stuff, and (if you want) call -db_release_unused_handles
when you're done as a hint to +
first_names is Jon. last_name is Salz.
first_names is Lars. last_name is Pind.
first_names is Michael. last_name is Yoon.
+Note that you never have to use ns_db anymore (including +ns_db gethandle)! Just start doing stuff, and (if you want) call +db_release_unused_handles when you're done as a hint to release the database handle. -
db_null
+
- db_null
-db_null
+db_nullReturns a value which can be used in a bind variable to represent the SQL -value
null
. See Nulls and Bind Variables +value null. See Nulls and Bind Variables above.- -
db_foreach
+db_foreach -db_foreach statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ +db_foreach statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] \ code_block [ if_no_rows if_no_rows_block ] -Performs the SQL query
sql
, executing -code_block
once for each row with variables set to -column values (or a set or array populated if-column_array
or -column_set
is specified). If the query returns no rows, executes -if_no_rows_block
(if provided).Example:
+Performs the SQL query sql, executing +code_block once for each row with variables set to +column values (or a set or array populated if -column_array or +column_set is specified). If the query returns no rows, executes +if_no_rows_block (if provided).
Example:
-db_foreach select_foo "select foo, bar from greeble" { - doc_body_append "<li>foo=$foo; bar=$bar\n" +db_foreach select_foo "select foo, bar from greeble" { + doc_body_append "<li>foo=$foo; bar=$bar\n" } if_no_rows { - doc_body_append "<li>There are no greebles in the database.\n" + doc_body_append "<li>There are no greebles in the database.\n" }-The code block may contain
break
statements (which terminate the -loop and flush the database handle) andcontinue
statements -(which continue to the next row of the loop).db_1row
-db_1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ +The code block may contain break statements (which terminate the +loop and flush the database handle) and continue statements +(which continue to the next row of the loop).- db_1row
+db_1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] -Performs the SQL query
sql
, setting variables to +Performs the SQL query sql, setting variables to column values. Raises an error if the query does not return exactly 1 row.
Example:
-db_1row select_foo "select foo, bar from greeble where greeble_id = $greeble_id" +db_1row select_foo "select foo, bar from greeble where greeble_id = $greeble_id" # Bombs if there's no such greeble! # Now $foo and $bar are set. -db_0or1row
-db_0or1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ +- db_0or1row
+db_0or1row statement-name sql [ -bind bind_set_id | -bind bind_value_list ] \ [ -column_array array_name | -column_set set_name ] -Performs the SQL query
sql
. If a row is returned, +Performs the SQL query sql. If a row is returned, sets variables to column values and returns 1. If no rows are returned, -returns 0. If more than one row is returned, throws an error.
db_string
-db_string statement-name sql [ -default default ] [ -bind bind_set_id | -bind bind_value_list ] +returns 0. If more than one row is returned, throws an error.- db_string
+db_string statement-name sql [ -default default ] [ -bind bind_set_id | -bind bind_value_list ]Returns the first column of the result of SQL query -
sql
. Ifsql
doesn't return a -row, returnsdefault
(or throws an error if -default
is unspecified). Analogous to -database_to_tcl_string
and -database_to_tcl_string_or_null
. +sql. If sql doesn't return a +row, returns default (or throws an error if +default is unspecified). Analogous to +database_to_tcl_string and +database_to_tcl_string_or_null. -db_nextval
-db_nextval sequence-name +- db_nextval
+db_nextval sequence-nameReturns the next value for the sequence sequence-name (using a -SQL statement like
SELECT
sequence-name
.nextval FROM -DUAL
). If sequence pooling is enabled for the sequence, transparently +SQL statement like SELECT sequence-name.nextval FROM +DUAL). If sequence pooling is enabled for the sequence, transparently uses a value from the pool if available to save a round-trip to the database. -db_list
-db_list statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +- db_list
+db_list statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list of the values in the first column of the result of SQL -query
sql
. Ifsql
doesn't +query sql. If sql doesn't return any rows, returns an empty list. Analogous to -database_to_tcl_list
. +database_to_tcl_list. -db_list_of_lists
-db_list_of_lists statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +- db_list_of_lists
+db_list_of_lists statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a Tcl list, each element of which is a list of all column values -in a row of the result of SQL query
sql
. If -sql
doesn't return any rows, returns an empty list. -(Analogous todatabase_to_tcl_list_list
.) +in a row of the result of SQL query sql. If +sql doesn't return any rows, returns an empty list. +(Analogous to database_to_tcl_list_list.) -db_list_of_ns_sets
-db_list_of_ns_sets statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +- db_list_of_ns_sets
+db_list_of_ns_sets statement-name sql [ -bind bind_set_id | -bind bind_value_list ]Returns a list of ns_sets with the values of each column of each row - returned by the
sql
query specified. -db_dml
-db_dml statement-name sql \ + returned by the sql query specified. +- db_dml
+db_dml statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ [ -blobs blob_list | -clobs clob_list | -blob_files blob_file_list | -clob_files clob_file_list ] -Performs the DML or DDL statement
sql
.If a length-n list of blobs or clobs is provided, then the SQL +
Performs the DML or DDL statement sql.
If a length-n list of blobs or clobs is provided, then the SQL should return n blobs or clobs into the bind variables -
:1
,:2
, ... :n
. -blobs
orclobs
, if specified, +:1, :2, ... :n. +blobs or clobs, if specified, should be a list of individual BLOBs or CLOBs to insert; -blob_files
orclob_files
, if +blob_files or clob_files, if specified, should be a list of paths to files containing the data to -insert. Only one of-blobs
,-clobs
, --blob_files
, and-clob_files
may be provided.Example:
+insert. Only one of -blobs, -clobs, +-blob_files, and -clob_files may be provided.Example:
-db_dml insert_photos " +db_dml insert_photos " insert photos(photo_id, image, thumbnail_image) values(photo_id_seq.nextval, empty_blob(), empty_blob()) returning image, thumbnail_image into :1, :2 - " -blob_files [list "/var/tmp/the_photo" "/var/tmp/the_thumbnail"] + " -blob_files [list "/var/tmp/the_photo" "/var/tmp/the_thumbnail"]-This inserts a new row into the
photos
table, with the contents -of the files/var/tmp/the_photo
and -/var/tmp/the_thumbnail
in theimage
and -thumbnail
columns, respectively. +This inserts a new row into the photos table, with the contents +of the files /var/tmp/the_photo and +/var/tmp/the_thumbnail in the image and +thumbnail columns, respectively.- -
db_write_clob
, -db_write_blob
, -db_blob_get_file
+db_write_clob, +db_write_blob, +db_blob_get_file -db_write_clob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +db_write_clob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] -db_write_blob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +db_write_blob statement-name sql [ -bind bind_set_id | -bind bind_value_list ] -db_blob_get_file statement-name sql [ -bind bind_set_id | -bind bind_value_list ] -Analagous to
ns_ora write_clob/write_blob/blob_get_file
. +db_blob_get_file statement-name sql [ -bind bind_set_id | -bind bind_value_list ] +Analagous to ns_ora write_clob/write_blob/blob_get_file. -
db_release_unused_handles
-db_release_unused_handles -
Releases any allocated, unused database handles.
db_transaction
-db_transaction code_block [ on_error { code_block } ] -Executes
code_block
transactionally. Nested -transactions are supported (end transaction
is transparently -ns_db dml
'ed when the outermost transaction completes). The -db_abort_transaction
command can be used to abort all levels of -transactions. It is possible to specify an optionalon_error
+- db_release_unused_handles
+db_release_unused_handles +
Releases any allocated, unused database handles.
- db_transaction
+db_transaction code_block [ on_error { code_block } ] +Executes code_block transactionally. Nested +transactions are supported (end transaction is transparently +ns_db dml'ed when the outermost transaction completes). The +db_abort_transaction command can be used to abort all levels of +transactions. It is possible to specify an optional on_error code block that will be executed if some code in code_block throws -an exception. The variable
errmsg
will be bound in that scope. -If there is noon_error
code, any errors will be propagated.Example:
+an exception. The variable errmsg will be bound in that scope. +If there is no on_error code, any errors will be propagated.Example:
proc replace_the_foo { col } { db_transaction { - db_dml "delete from foo" - db_dml "insert into foo(col) values($col)" + db_dml "delete from foo" + db_dml "insert into foo(col) values($col)" } } proc print_the_foo {} { - doc_body_append "foo is [db_string "select col from foo"]<br>\n" + doc_body_append "foo is [db_string "select col from foo"]<br>\n" } replace_the_foo 8 -print_the_foo ; # Writes out "foo is 8" +print_the_foo ; # Writes out "foo is 8" db_transaction { replace_the_foo 14 - print_the_foo ; # Writes out "foo is 14" - db_dml "insert into some_other_table(col) values(999)" + print_the_foo ; # Writes out "foo is 14" + db_dml "insert into some_other_table(col) values(999)" ... db_abort_transaction } on_error { - doc_body_append "Error in transaction: $errmsg" + doc_body_append "Error in transaction: $errmsg" } -print_the_foo ; # Writes out "foo is 8" +print_the_foo ; # Writes out "foo is 8" -db_abort_transaction
+- db_abort_transaction
-db_abort_transaction +db_abort_transactionAborts all levels of a transaction. That is if this is called within several nested transactions, all of them are terminated. Use this insetead of -
db_dml "abort" "abort transaction"
. +db_dml "abort" "abort transaction". -db_multirow
-db_multirow [ -local ] [ -append ] [ -extend column_list ] \ +- db_multirow
+db_multirow [ -local ] [ -append ] [ -extend column_list ] \ var-name statement-name sql \ [ -bind bind_set_id | -bind bind_value_list ] \ code_block [ if_no_rows if_no_rows_block ]- Performs the SQL query
sql
, saving results in variables + Performs the SQL query sql, saving results in variables of the form -var_name:1
,var_name:2
, etc, - settingvar_name:rowcount
to the total number - of rows, and settingvar_name:columns
to a + var_name:1, var_name:2, etc, + setting var_name:rowcount to the total number + of rows, and setting var_name:columns to a list of column names.Each row also has a column, rownum, automatically added and set to the row number, starting with 1. Note that this will override any column in the SQL statement named 'rownum', also if you're using the Oracle rownum pseudo-column.
- If the
-local
is passed, the variables defined + If the -local is passed, the variables defined by db_multirow will be set locally (useful if you're compiling dynamic templates in a function or similar situations).@@ -576,19 +576,19 @@ multirow.
You may also add additional, computed columns to the multirow, using the -
-extend { col_1 col_2 ... }
switch. This is + -extend { col_1 col_2 ... } switch. This is useful for things like constructing a URL for the object retrieved by the query.If you're constructing your multirow through multiple queries with the same set of columns, but with different rows, you can use the -
-append
switch. This causes the rows returned by this query + -append switch. This causes the rows returned by this query to be appended to the rows already in the multirow, instead of starting a clean multirow, as is the normal behavior. The columns must match the columns in the original multirow, or an error will be thrown.- Your code block may call
continue
in order to skip a row - and not include it in the multirow. Or you can callbreak
+ Your code block may call continue in order to skip a row + and not include it in the multirow. Or you can call break to skip this row and quit looping.@@ -603,28 +603,28 @@ } { set user_url [acs_community_member_url -user_id $user_id] } -
db_resultrows
-db_resultrows +
- db_resultrows
+db_resultrows
Returns the number of rows affected or returned by the previous statement. -
db_with_handle
-db_with_handle var code_block -Places a database handle into the variable
var
and -executescode_block
. This is useful when you don't -want to have to use the new API (db_foreach
, -db_1row
, etc.), but need to use database handles explicitly.Example:
+- db_with_handle
+db_with_handle var code_block +Places a database handle into the variable var and +executes code_block. This is useful when you don't +want to have to use the new API (db_foreach, +db_1row, etc.), but need to use database handles explicitly.
Example:
proc lookup_the_foo { foo } { db_with_handle db { - return [db_string unused "select ..."] + return [db_string unused "select ..."] } } db_with_handle db { # Now there's a database handle in $db. - set selection [ns_db select $db "select foo from bar"] + set selection [ns_db select $db "select foo from bar"] while { [ns_db getrow $db $selection] } { set_variables_after_query @@ -633,99 +633,99 @@ }- - -
+ + db_name -
- + + - -db_name
- + + db_name +Returns the name of the database, as returned by the driver.
- - -
+ + db_type -
- + + - -db_type
- + + db_type +Returns the RDBMS type (i.e. oracle, postgresql) this OpenACS installation is using. The nsv ad_database_type is set up during the bootstrap process.
- - -
+ + db_compatible_rdbms_p -
- + + - db_compatible_rdbms_p db_type + db_compatible_rdbms_p db_typeReturns 1 if the given db_type is compatible with the current RDBMS.
- - -
+ + db_package_supports_rdbms_p -
- + + - db_package_supports_rdbms_p db_type_list + db_package_supports_rdbms_p db_type_listReturns 1 if db_type_list contains the current RDMBS type. A package intended to run with a given RDBMS must note this in it's package info file regardless of whether or not it actually uses the database.
- - -
+ + db_legacy_package_p -
- + + - db_legacy_package_p db_type_list + db_legacy_package_p db_type_listReturns 1 if the package is a legacy package. We can only tell for certain if it explicitly supports Oracle 8.1.6 rather than the OpenACS more general oracle.
- - -
+ + db_version -
- + + - db_version + db_versionReturns the RDBMS version (i.e. 8.1.6 is a recent Oracle version; 7.1 a recent PostgreSQL version.
- - -
+ + db_current_rdbms -
- + + - db_current_rdbms + db_current_rdbmsReturns the current rdbms type and version.
- - -
+ + db_known_database_types -
- + + - db_known_database_types + db_known_database_typesReturns a list of three-element lists describing the database engines known to OpenACS. Each sublist contains the internal database name (used in file - paths, etc), the driver name, and a "pretty name" to be used in selection + paths, etc), the driver name, and a "pretty name" to be used in selection forms displayed to the user.
The nsv containing the list is initialized by the bootstrap script and should never be referenced directly by user code. Returns the current rdbms type and version. -
($Id$)View comments on this page at openacs.org +
Table of Contents
+ +
By Claus Rasmussen, with additions by Roberto Mello, Vinod Kurup, and the OpenACS Community -
+
OpenACS™ is a powerful system with incredible possibilities and applications, but this power comes with some complexity and a steep learning curve @@ -41,40 +41,40 @@ This document attempts to shape ongoing documentation efforts by using principles of continual improvement to re-engineer documentation production. -
Documentation production shares many of the challenges of software development, such as managing contributions, revisions and the (editorial) release cycle. This is yet another experiment in improving documentation --this time by using principles of continual improvement to focus the on-going efforts. These processes are outlined as project management phases: -
- Requirements phase is about setting goals and +
+ Requirements phase is about setting goals and specifications, and includes exploration of scenarios, use cases - etc. As an example, see the + etc. As an example, see the OpenACS Documentation Requirements Template which focuses on systems requirements for developers. -
- Strategy phase is about creating an approach +
+ Strategy phase is about creating an approach to doing work. It sets behavioral guidelines and boundaries that help keep perspective on how efforts are directed. OpenACS developers discuss strategy when coordinating efforts such as code revisioning and new features. -
- Planning phase is about explicitly stating +
+ Planning phase is about explicitly stating the way to implement the strategy as a set of methods. OpenACS system design requires planning. For example, see - OpenACS + OpenACS documentation template planning relating to package design. -
- Implementation phase is about performing the +
+ Implementation phase is about performing the work according to the plan, where decisions on how to handle unforseen circumstances are guided by the strategy and requirements. -
- Verification phase measures how well the plan +
+ Verification phase measures how well the plan was implemented. Success is measured by A) verifying if the project has met the established goals, and B) reviewing for ongoing problem areas etc. OpenACS follows verification @@ -88,56 +88,56 @@ phases are mainly organized and fulfilled by a designated documentation maintainer. Hopefully the following sections will help spur greater direct participation by the OpenACS community. -
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
- clarity in presentation. Life with - qmail is a recommended example of "rated high" online +
+ clarity in presentation. Life with + qmail is a recommended example of "rated high" online documentation. -
+
Avoid requirements that significantly increase the labor required to maintain documentation. -
+
Use best practices learned from the print world, web, and other media, about use of gamma, space, writing style etc. -
+
Consistency in publishing -Establishing and adhering to publishing standards -
+
Use standardized language -Use international English (without slang or colloquial terms) for ESL (English as a second language) readers (and making translation easier for those interested in translating the documentation for internationalization efforts). -
+
All jargon used in documentation needs to be defined. Use standardized terms when available, avoiding implicit understanding of specific OpenACS terms. -
+
Document titles (for example on html pages) should include whole document title (as in book title): (chapter title) : (section), so that bookmarks etc. indicate location in a manner similar to pages in books (in print publishing world). -
+
Organize document according to the needs of the reader (which may be different than the wishes of the writers). -
+
Do not make informal exclamations about difficulty/ease for users to complete tasks or understand... for - example, "Simply...". Readers come from many different + example, "Simply...". Readers come from many different backgrounds --remember that the greater audience is likely as varied as the readers on the internet--- If important, state pre-conditions or knowledge requirements etc. if different than the rest of the - context of the document. For example, "requires basic + context of the document. For example, "requires basic competency with a text-based editor such as vi or emacs - via telnet" -
+ via telnet" +
Show where to find current information instead of writing about current info that becomes obsolete. If the information is not found elsewhere, then create one place for it, where @@ -152,20 +152,20 @@ still be in 1 area, using a common layout of perhaps summary, introduction and discussion requiring increasing expertise, complexity or specificity. -
+
Consistency in link descriptions -When link urls refer to whole documents, make the link (anchor wrapped title) that points to a document with the same title and/or heading of the document. -
+
Consider OpenACS documentation as a set of books (an encyclopedic set organized like an atlas) that contains volumes (books). Each book contains chapters and sections much like how DocBook examples are shown, where each chapter is a web page. This designation could help create an OpenACs book in print, and help new readers visualize how the documentation is organized. -
+
The use licenses between OpenACS and Arsdigita's ACS are not compatible, thereby creating strict limits on how much OpenACS developers should have access to Arsdigita code and @@ -175,60 +175,60 @@ inference of license noncompliance, while recognizing the important work accomplished by Philip Greenspun, Arsdigita, and the early ACS adopters. -
+
Use a consistent general outline for each book. -
+
Introduction (includes purpose/goal), Glossary of terms, Credits, License, Copyright, Revision History -
+
Table of Contents (TOC)s for each book: the end-users, content and site administrators, marketing, developer tutorial, and developers. -
+
Priorities of order and content vary based on each of the different readers mentioned. The developers guide should be organized to be most useful to the priorities of developers, while being consistent with the general documentation requirements including publishing strategy, style etc. -
+
Use generic DocBook syntax to maximize reader familiarity with the documents.
- <book><title><part label="Part 1"><etc...> + <book><title><part label="Part 1"><etc...>
-
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS end-user documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
+
End-users should not have to read docs to use the system. -
+
Include how to get help. How and where to find answers, contact others, what to do if one gets an AOLserver or other error when using the system. Include types of available support (open-source, private commercial etc.) including references. -
+
Explain/foster understanding of the overall structure of the system. This would be an overview of the system components, how it works, and how to find out more or dig deeper... To promote the system by presenting the history of the system, and writing about some tacit knowledge re: OpenACS.org and the opensource culture. -
+
Introduce and inspire readers about the uses, benefits, and the possibilities this system brings (think customer solution, customer cost, convenience, value). A comprehensive community communications system; How this system is valuable to users; Reasons others use OpenACS - (with quotes in their own words) "...the most important + (with quotes in their own words) "...the most important thing that the ACS does is manage users, i.e. provide a way to group, view and manipulate members of the web community. - -- Talli Somekh, September 19, 2001" using it to + -- Talli Somekh, September 19, 2001" using it to communicate, cooperate, collaborate... OpenACS offers directed content functionality with the OpenACS templating system. ... OpenACS is more than a data collection and @@ -238,32 +238,32 @@ is built and the library of tried and tested community building tools that are waiting to be added. It seems that most portals just add another layer of complexity to the - cake. See Slides on OACS + cake. See Slides on OACS features...a set of slides on OACS features that can be used for beginners who want to know OACS is about and what they can do with it. Screen captures that highlight features. Example shows BBoard, calendar, news, file storage, wimpy point, ticket tracking. An OpenACS tour; an abbreviated, interactive set of demo pages. -
+
From a marketing perspective, -
- differentiate "product" by highlighting features, +
+ differentiate "product" by highlighting features, performance quality, conformance to standards, durability (handling of technological obsolescence), reliability, repairability, style of use, design (strategy in design, specifications, integrated, well-matched systems etc). -
- differentiate "service" by highlighting software +
+ differentiate "service" by highlighting software availability (licensing and completeness from mature to early adopters or development versions), community incident support, project collaborative opportunities, and contractor support availability -
+
differentiate price (economic considerations of opensource and features) -
+
Discussion and details should rely on meeting criteria of design, completeness of implementation, and related system strengths and weaknesses. Marketing should not @@ -272,10 +272,10 @@ opportunities and threats when compared to other systems for a specific purpose, and thus is inappropriate (and becomes stale quickly) for general documentation. -
+
When identifying subsystems, such as tcl, include links to their marketing material if available. -
+
create an example/template comparison table that shows versions of OpenACS and other systems (commonly competing against OpenACS) versus a summary feature list @@ -284,22 +284,22 @@ information was gathered, since information is likely volatile.
-
+
To build awareness about OpenACS, consider product differentiation: form, features, performance quality, conformance quality (to standards and requirements), durability, reliability, repairability, style, design: the deliberate planning of these product attributes. -
+
Include jargon definitions, glossary, FAQs, site map/index, including where to find Instructions for using the packages. FAQ should refer like answers to the same place for consistency, brevity and maintainability. -
+
Explain/tutorial on how the UI works (links do more than go to places, they are active), Page flow, descriptions of form elements; browser/interface strengths and limitations (cookies, other) -
+
Discuss criteria used to decide which features are important, and the quality of the implementation from a users perspective. Each project implementation places a @@ -308,19 +308,19 @@ than an actual comparison.
Package documentation requirements have additional requirements. -
+
A list of all packages, their names, their purposes, what they can and cannot do (strengths, limitations), what differentiates them from similar packages, minimal description, current version, implementation status, author/maintainers, link(s) to more info. Current version - available at the repository. -
+ available at the repository. +
Include dependencies/requirements, known conflicts, and comments from the real world edited into a longer description to quickly learn if a package is appropriate for specific projects. -
+
Create a long bulleted list of features. Feature list should go deeper than high-level feature lists and look at the quality of the implementations (from the user's perspective, @@ -331,233 +331,233 @@ supported by the current e-commerce module? There are some packages where the name is clear enough, but what are the limitations of the standard package? -
+
End-user docs should not be duplicative. The package description information and almost everything about a package for administrators and developers is already described in the package itself through two basic - development document templates: a - Requirements Template and Detailed + development document templates: a + Requirements Template and Detailed Design Document. -
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS administrators' documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
+
For each requirement below, include links to developer tutorials and other documentation for more detail. -
+
Describe a structural overview of a working system and how - the components work together. "The Layered Cake view" a + the components work together. "The Layered Cake view" a general network view of system; a table showing system levels versus roles to help with understanding how the subsystems are interconnected. -
+
Provide a comprehensive description of typical administrative processes for operating an OpenACS system responsibly, including reading logs and command line views that describe status of various active processes. -
+
Create a list of administrative tools that are useful to administrating OpenACS, including developer support, schema-browser and api browser. Link to AOLserver's config file documentation. -
+
Resources on high level subjects such as web services, security guidelines -
+
Describe typical skill sets (and perhaps mapped to standardized job titles) for administrating an OpenACS system (human-resources style). For a subsite admin/moderator attributes might include trustworthy, sociable, familiarity with the applications and subsystems, work/group communication skills et cetera -
+
Describe how to set up typical site moderation and - administration including parameters, permissions, "Hello - World" page -
+ administration including parameters, permissions, "Hello + World" page +
Show directory structure of a typical package, explanation of the various file types in a package (tcl,adp,xql) and how those relate to the previously described subsystems, when they get refreshed etc. -
- Ways to build a "Hello World" page -
+
+ Ways to build a "Hello World" page +
Show examples of how the OpenACS templating system is used, including portal sections of pages. For example, create a customised auto-refreshing startpage using lars-blogger, a photo gallery, and latest posts from a forum. This should rely heavily on documentation existing elsewhere to keep current. This would essentially be a heavily annotated list of links. -
+
Show ways of modifying the look and feel across pages of an OpenACS website. Refer to the skins package tutorial. -
+
Describe a methodology for diagnosing problems, finding error statements and interpreting them --for OpenACS and the underlying processes. -
+
FAQs: Administration tasks commonly discussed on boards: admin page flow, how to change the looks of a subsite with a - new master.adp, options on "user pages" , a quick + new master.adp, options on "user pages" , a quick introduction to the functions and processes. info about the user variables, file locations -
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS installation documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
- state installation prerequisites. For example: "You should +
+ state installation prerequisites. For example: "You should read through the installation process to familiarize yourself with the installation process, before beginning an - installation." -
+ installation." +
list critical decisions (perhaps as questions) that need to be made before starting: which OS, which DB, which aolserver version, system name, dependencies et cetera. Maybe summarize - options as tables or decision-trees. For example, "As you + options as tables or decision-trees. For example, "As you proceed throughout the installation, you will be acting on decisions that have an impact on how the remaining part of the system is installed. Here is a list of questions you - should answer before beginning." -
+ should answer before beginning." +
list pre-installation assumptions -
+
Show chronological overview of the process of installing a system to full working status: Install operating system with supporting software, configure with preparations for OpenACS, RDBMS(s) install and configure, Webserver install and configure, OpenACS install and configure, post-install work -
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS developer tutorial documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
+
list learning prerequisites to customize, fix, and improve OACS modules, and create new ones. You are expected to have read and understand the information [minimum requirements similar to adept at Using OpenACS Administrating Guide] before reading this guide. -
+
Refer to development documentation instead of duplicating here -
+
List suggestions for installing and setting up a development environment; these can be annotated links to the installation documentation -
+
Provide working examples that highlight the various subsystems, tcl environment, OpenACS protocols, aolserver template and ns_* commands, OpenACS templating, sql queries, db triggers, scheduling protocols, how to use the page contract, how to get the accessing user_id etc -
+
Show how to construct basic SQL queries using the db API, -
+
The life of an http request to a dynamic, templated page -
+
General rules to follow for stability, scalability -
+
Show the step by step customizing of an existing package that meets current recommended coding styles of OpenACS package development, by referring to developer resources. -
- Use the ArsDigita problem sets and "what Lars produced for ACS Java" as inspiration for a +
+ Use the ArsDigita problem sets and "what Lars produced for ACS Java" as inspiration for a PostgreSQL equivalent tutorial about developing a new OpenACS package including discussion of the significance of the package documentation templates -
+
Include a summary of important links used by developers -
+
Note any deprecated tools and methods by linking to prior versions instead of describing them in current docs -
By the OpenACS Community. This section is a collection of documentation requirements that have been expressed in the OpenACS forums to 4th July 2003.
OpenACS developer documentation should meet the following requirements. No significance has been given to the order presented, topic breadth or depth here. -
+
list documentation assumptions, such as familiarity with modifying OpenACS packages. All kernel docs are here etc. -
+
This documentation should be written for ongoing use by developers, not as a tutorial. -
+
List of practical development and diagnostics tools and methodologies. -
+
List of OpenACS development resources, api-doc, schema-browser, developer-support package etc. -
+
Identify each OpenACS subsystem, explain why it is used (instead of other choices). In the case of subsystems that are developed outside of OpenACS such as tcl, include external references to development and reference areas. -
+
Show current engineering standards and indicate where changes to the standards are in the works. -
+
Sections should be dedicated to DotLRN standards as well, if they are not available elsewhere. -
+
Add overview diagrams showing the core parts of the datamodel including an updated summary of Greenspun's Chapter 4: Data Models and the Object System -
+
package design guidelines and development process templates including planning, core functions, testing, usability, and creating case studies -
- Standard package conventions, where to see "model" code, and +
+ Standard package conventions, where to see "model" code, and guidelines (or where to find them) for: -
+
programming tcl/sql -
+
using the acs-api -
+
ad_form -
+
coding permissions -
+
OpenACS objects -
+
scheduled protocols -
+
call backs -
+
directory structure -
+
user interface -
+
widgets -
+
package_name and type_extension_table -
+
adding optional services, including search, general comments, attachments, notifications, workflow, CR and the new CR Tcl API
-
+
Document kernel coding requirements, strategy and guidelines to help code changers make decisions that meet kernel designers' criteria -
OpenACS documentation development is subject to the constraints of the software project development and release - methods and cycles (Using CVS with OpenACS). + methods and cycles (Section , “Using CVS with OpenACS”). Essentially, all phases of work may be active to accommodate the asynchronous nature of multiple subprojects evolving by the efforts of a global base of participants with culturally @@ -567,50 +567,50 @@ involve others by collaborating or obtaining guidance or feedback (peer review) to distribute the workload and increase the overall value of output for the OpenACS project. -
OpenACS documentation is taking a dual approach to publishing. Documentation that is subject to rapid change and participation by - the OpenACS community is managed through the OpenACS + the OpenACS community is managed through the OpenACS xowiki Documentation Project Formal documents that tend to remain static and require more expressive publishing tools will be marked up to conform to the - DocBook XML + DocBook XML DTD. The remaining discussion is about publishing using Docbook.
- + is a publishing standard based on XML with similar goals to the OpenACS Documentation project. Some specific reasons why we are using DocBook: -
+
It is open-source. -
+
A growing community surrounds DocBook (has - mailing lists) -
+ mailing lists) +
A number of free and commercial - tools are available + tools are available for editing and publishing DocBook documents. -
+
It enables us to publish in a variety of formats. -
+
XML separates content from presentation: It relieves each contributor of the burden of presentation, freeing each writer to focus on content and sharing knowledge. -
+
It is well tested technology. It has been in development - since the early 1990's). + since the early 1990's).
Reasons why we are using Docbook XML instead of Docbook SGML: -
+
Consistency and history. We started with a collection of DocBook XML files that ArsDigita wrote. Trying to re-write them to conform to the SGML DTD would be unnecessary work. -
+
XML does not require extra effort. Writing in XML is almost identical to SGML, with a couple extra rules. More details in the - LDP Author Guide. -
+ LDP Author Guide. +
The tool chain has matured. xsltproc and other XML
based tools have improved to the point where they are about as good as
the SGML tools. Both can output html and pdf formats.
@@ -629,50 +629,50 @@
should be able to extract details of a specific reference from
a bibliographic (table) and present a footnote at the
point where referenced. DocBook 4.4 allows for this with
- bibliocoverage
,
- bibliorelation
, and
- bibliosource
. DocBook:
+ bibliocoverage,
+ bibliorelation, and
+ bibliosource. DocBook:
The Definitive Guide is a good start for learning how
to represent paper-based books online.
The following DocBook primer walks you through the basics, and should cover the needs for 95 percent of the documentation we produce. You are welcome to explore DocBook's - + list of elements and use more exotic features in your documents. The list is made up of SGML-elements but basically - the same elements are valid in the XML DTD as long as you remember to: - -
You are going to need the following to work with the OpenACS Docbook XML documentation: -
+ Docbook XML DTD - The document type definition for XML. You can find an RPM or DEB package or you can download a zip file from the site linked from here. -
- XSL +
+ XSL Stylesheets (docbook-xsl) - The stylesheets to convert to HTML. We have been using a stylesheet based upon NWalsh's chunk.xsl. -
- xsltproc
- The processor that
+
+ xsltproc - The processor that will take an XML document and, given a xsl stylesheet, convert it to HTML. It needs libxml2 and libxslt (available in RPM and - DEB formats or from xmlsoft.org. -
+ DEB formats or from xmlsoft.org. +
Some editing tool. A popular one is Emacs with the psgml and nXML - modes. The LDP Author - Guide and DocBook + modes. The LDP Author + Guide and DocBook Wiki list some alternates. -
After you have the tools mentioned above, you need to define a title for your document. Then start thinking about the possible sections and subsections you will have in your document. Make @@ -682,200 +682,200 @@ please e-mail the gatekeeper in charge of documentation.
You can look at some templates for documents (in Docbook XML) in - the sources + the sources for acs-core-docs, especially the Detailed Design Documentation Template and the System/Application Requirements Template. -
- The documentation for each package will make up a little "book" that is structured like this +
+ The documentation for each package will make up a little "book" that is structured like this - examples are emphasized: - +
- book : Docs for one package - templating + book : Docs for one package - templating | - +--chapter : One section - for developers + +--chapter : One section - for developers | ---------+------------------------------------------------------ | - +--sect1 : Single document - requirements + +--sect1 : Single document - requirements | - +--sect2 : Sections - functional requirements + +--sect2 : Sections - functional requirements | - +--sect3 : Subsections - Programmer's API + +--sect3 : Subsections - Programmer's API | - ... : ... + ... : ...
The actual content is split up into documents that start at a
- sect1
-level. These are then tied together in a top-level document that
+ sect1-level. These are then tied together in a top-level document that
contains all the information above the line. This will be explained in more detail in a later document,
and we will provide a set of templates for documenting an entire package.
For now you can take a look at the - sources of these DocBook documents + sources of these DocBook documents to get an idea of how they are tied together. -
-
- Given that your job starts at the sect1
-level, all your documents should open with a
- <sect1>
-tag and end
- with the corresponding </sect1>
.
+
+ + Given that your job starts at the sect1-level, all your documents should open with a + <sect1>-tag and end + with the corresponding </sect1>.
-
- You need to feed every <sect1>
two attributes. The first attribute,
- id
, is standard and can be used with all elements. It comes in very
- handy when interlinking between documents (more about this when talking about links in Links).
- The value of id
has to be unique
- throughout the book you're making since the id
's in your
- sect1
's will turn into filenames when the book is parsed into HTML.
+
+ You need to feed every <sect1> two attributes. The first attribute,
+ id, is standard and can be used with all elements. It comes in very
+ handy when interlinking between documents (more about this when talking about links in Section , “Links”).
+ The value of id has to be unique
+ throughout the book you're making since the id's in your
+ sect1's will turn into filenames when the book is parsed into HTML.
-
- The other attribute is xreflabel
. The value of this is the text that will appear
- as the link when referring to this sect1
.
+
+ The other attribute is xreflabel. The value of this is the text that will appear
+ as the link when referring to this sect1.
Right after the opening tag you put the title of the document - this is usually the same as
- xreflabel
-attribute. E.g. the top level of the document you're
+ xreflabel-attribute. E.g. the top level of the document you're
reading right now looks like this:
-<sect1 id="docbook-primer" xreflabel="DocBook Primer"> +<sect1 id="docbook-primer" xreflabel="DocBook Primer"> <title>DocBook Primer</title> ... </sect1>
-
+
Inside this container your document will be split up into
- <sect2>
's,
- each with the same requirements - id
and xreflabel
- attributes, and a <title>
-tag inside. Actually, the xreflabel
is never required in sections, but it makes linking to that section a lot easier.
+ <sect2>'s,
+ each with the same requirements - id and xreflabel
+ attributes, and a <title>-tag inside. Actually, the xreflabel is never required in sections, but it makes linking to that section a lot easier.
When it comes to naming your
- sect2
's and below, prefix them with some abbreviation of the id
in the sect1
such as requirements-overview
.
-
- + sect2's and below, prefix them with some abbreviation of the id in the sect1 such as requirements-overview. +
+
For displaying a snippet of code, a filename or anything else you just want to appear as a part of
a sentence, we use
- <computeroutput>
- and <code>
+ <computeroutput>
+ and <code><code></code>
tags.
- These replace the HTML-tag <code>
tag,
+ These replace the HTML-tag <code><code></code> tag,
depending on whether the tag is describing computer output or
computer code.
For bigger chunks of code such as SQL-blocks, the tag
- <programlisting>
is used. Just wrap your code block in it; mono-spacing, indents and all that stuff is taken care of
+ <programlisting> is used. Just wrap your code block in it; mono-spacing, indents and all that stuff is taken care of
automatically.
For expressing user interaction via a terminal window, we wrap
- the <screen>
- tag around text that has been wrapped by combinations of <computeroutput>
- and <userinput>
-
- + the <screen> + tag around text that has been wrapped by combinations of <computeroutput> + and <userinput> +
+ Linking falls into two different categories: inside the book you're making and outside: -
- By having unique id
's you can cross-reference any part of your book
+
+ By having unique id's you can cross-reference any part of your book with a simple tag, regardless of where that part is. -
Check out how I link to a subsection of the Developer's Guide:
Put this in your XML:
+Check out how I link to a subsection of the Developer's Guide:
Put this in your XML:
- Find information about creating a package in -<xref linkend="packages-making-a-package"></xref>. +<xref linkend="packages-making-a-package"></xref>.And the output is:
- Find information about creating a package in -Making a Package. +Making a Package.Note that even though this is an empty tag, you have to either: -
- Provide the end-tag,
</xref>
, or -- Put a slash before the ending-bracket:
<xref linkend="blahblah"/>
-If the section you link to hasn't a specified
xreflabel
-attribute, +
+ Provide the end-tag, </xref>, or +
+ Put a slash before the ending-bracket: <xref linkend="blahblah"/> +
If the section you link to hasn't a specified xreflabel-attribute, the link is going to look like this:
Put this in your XML:
-Find information about what a package looks like in -<xref linkend="packages-looks"></xref>. +<xref linkend="packages-looks"></xref>.And the output is:
- Find information about what a package looks like in -What a Package Looks Like. +Section , “What a Package Looks Like”.- Note that since I haven't provided an
xreflabel
for the subsection, -packages-looks
, the + Note that since I haven't provided an xreflabel for the subsection, + packages-looks, the parser will try its best to explain where the link takes you. -
+
If you're hyper-linking out of the documentation, it works almost the same way as HTML - the tag is just
a little different
- (<ulink>
):
+ (<ulink>):
-
<ulink url="http://www.oracle.com/">Oracle Corporation</ulink>
+
<ulink url="http://www.oracle.com/">Oracle Corporation</ulink>
....will create a hyper-link to Oracle in the HTML-version of the documentation. -
NOTE: Do NOT use +
NOTE: Do NOT use
ampersands in your hyperlinks. These are reserved for
- referencing entities.
- To create an ampersand, use the entity &
+ referencing entities.
+ To create an ampersand, use the entity <code>&</code>
-
- Note: The graphics guidelines + Note: The graphics guidelines are not written in stone. Use another valid approach if it works better for you.
-
+
To insert a graphic we use the elements
- <mediaobject>
,
- <imageobject>
,
- <imagedata>
,
+ <mediaobject>,
+ <imageobject>,
+ <imagedata>,
and
- <textobject>
.
+ <textobject>.
Two versions of all graphics are required. One for the Web
(usually a JPEG or GIF), and a brief text description. The
description becomes the ALT text. You can also supply a version for print (EPS).
<mediaobject> <imageobject> - <imagedata fileref="images/rp-flow.gif" format="GIF" align="center"/> + <imagedata fileref="images/rp-flow.gif" format="GIF" align="center"/> </imageobject> <imageobject> - <imagedata fileref="images/rp-flow.eps" format="EPS" align="center"/> + <imagedata fileref="images/rp-flow.eps" format="EPS" align="center"/> </imageobject> <textobject> <phrase>This is an image of the flow in the Request Processor</phrase> </textobject> </mediaobject>
- Put your graphics in a separate directory ("images") and link to them + Put your graphics in a separate directory ("images") and link to them only with relative paths. -
+ Here's how you make the DocBook equivalent of the three usual HTML-lists: -
- Making an unordered list is pretty much like doing the same thing in HTML - if you close your <li>
, that is. The only differences are that each list item has to be wrapped in something more, such as
- <para>
, and that the tags are called
- <itemizedlist>
+
+ Making an unordered list is pretty much like doing the same thing in HTML - if you close your <li>, that is. The only differences are that each list item has to be wrapped in something more, such as
+ <para>, and that the tags are called
+ <itemizedlist>
and
- <listitem>
:
+ <listitem>:
<itemizedlist> <listitem><para>Stuff goes here</para></listitem> <listitem><para>More stuff goes here</para></listitem> </itemizedlist> -
+
The ordered list is like the preceding, except that you use
- <orderedlist>
instead:
+ <orderedlist> instead:<orderedlist> <listitem><para>Stuff goes here</para></listitem> <listitem><para>More stuff goes here</para></listitem> </orderedlist> -
- This kind of list is called a variablelist
and these are the tags you'll need to
+
+ This kind of list is called a variablelist and these are the tags you'll need to
make it happen:
- <variablelist>
,
- <varlistentry>
,
- <term>
and
- <listitem>
:
+ <variablelist>, + <varlistentry>, + <term> and + <listitem>:<variablelist> <varlistentry> @@ -889,14 +889,14 @@ </varlistentry> </variablelist> -
+
DocBook supports several types of tables, but in most cases, the
- <informaltable>
+ <informaltable>
is enough:
-<informaltable frame="all"> - <tgroup cols="3"> +<informaltable frame="all"> + <tgroup cols="3"> <tbody> <row> @@ -924,26 +924,26 @@ With our current XSL-style-sheet, the output of the markup above will be a simple HTML-table:
a1 b1 c1 a2 b2 c2 a3 b3 c3 If you want cells to span more than one row or column, it gets a bit more complicated - check out -
<table>
+ <table> for an example. -
+
Our documentation uses two flavors of emphasis - italics and bold type. DocBook uses one -
- <emphasis>
.
+ <emphasis>.
- The <emphasis>
tag defaults to italics when parsed. If you're looking for
- emphasizing with bold type, use <emphasis role="strong">
.
-
+ The <emphasis> tag defaults to italics when parsed. If you're looking for + emphasizing with bold type, use <emphasis role="strong">. +
Words that are marked as index-words are referenced in an index in the final, parsed document.
Use
- <indexterm>
,
- <primary>
and
- <secondary>
+ <indexterm>,
+ <primary> and
+ <secondary>
for this. See these links for an explanation.
-
This section is quoted almost verbatim from the LDP Author Guide.
- Once you have the Docbook Tools +
This section is quoted almost verbatim from the LDP Author Guide.
+ Once you have the Docbook Tools installed, you can convert your xml documents to HTML or other formats.
@@ -955,52 +955,52 @@ To generate a single HTML file from your DocBook XML file, use the command:
-bash$
xsltproc -o outputfilename.xml /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/html.xsl filename.xml
-
- This example uses Daniel Veillard's xsltproc command available - as part of libxslt from http://www.xmlsoft.org/XSLT/. +bash$ xsltproc -o outputfilename.xml /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/html.xsl filename.xml +
+ This example uses Daniel Veillard's xsltproc command available + as part of libxslt from http://www.xmlsoft.org/XSLT/. If you are using other XML processors such as Xalan or Saxon, you will need to change the command line appropriately.
To generate a set of linked HTML pages, with a separate page for each <chapter>, <sect1> or <appendix> tag, use the following command:
-bash$
xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/chunk.xsl filename.xml
+bash$ xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/chunk.xsl filename.xml
- You could also look at the acs-core-docs Makefile + You could also look at the acs-core-docs Makefile for examples of how these documents are generated. -
- The LDP Author +
+ The LDP Author Guide has a lot of good information, a table of - docbook elements and their "look" in HTML and lots of good links + docbook elements and their "look" in HTML and lots of good links for tools. -
+
James Clark - wrote nXML Mode, an alternative + wrote nXML Mode, an alternative to PSGML Mode. nXML Mode can validate a file as it is edited. -
+
David Lutterkort - wrote an intro to the PSGML Mode in Emacs -
+ wrote an intro to the PSGML Mode in Emacs +
James Clark's free Java parser - XP. Note that + XP. Note that this does not validate XML, only parses it. -
+ DocBook Tool for Linux: Converts docbook documents to a number of formats. NOTE: I only got these to work with Docbook SGML, NOT with Docbook XML. If you are able to make it work with our XML, please let us know. -
- AptConvert from PIXware is a Java editor that will produce +
+ AptConvert from PIXware is a Java editor that will produce DocBook documents and let you transform them into HTML and PDF for a local preview before you submit. -
+
In the process of transforming your HTML into XML, - HTML tidy - can be a handy tool to make your HTML "regexp'able". + HTML tidy + can be a handy tool to make your HTML "regexp'able". Brandoch Calef has made a - Perl + Perl script with directions (now via archive.org) that gets you most of the way. -
By Michael Bryzek
+ +By Michael Bryzek
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -Constraint naming standard is important for one reason: The SYS_* name oracle assigns to unnamed constraints is not very understandable. By correctly naming all contraints, we can quickly associate a particular constraint with our data model. This gives us two real advantages: -
We can quickly identify and fix any errors.
We can reliabily modify or drop constraints
+
We can quickly identify and fix any errors.
We can reliabily modify or drop constraints
-Oracle limits names, +Oracle limits names, in general, to 30 characters, which is hardly enough for a human readable constraint name. -
We propose the following naming convention for all constraints, with the following abbreviations taken from Oracle Docs at - + http://oradoc.photo.net/ora81/DOC/server.815/a67779/ch4e.htm#8953. Note that we shortened all of the constraint abbrevations to two characters to save room. -
Constraint type | Abbreviation |
---|---|
references (foreign key) | fk |
unique | un |
primary key | pk |
check | ck |
not null | nn |
+
Constraint type | Abbreviation |
---|---|
references (foreign key) | fk |
unique | un |
primary key | pk |
check | ck |
not null | nn |
<table name>_<column_name>_<constraint abbreviation>
In reality, this won't be possible because of the character limitation on names inside oracle. When the name is too long, we will follow these two steps in order: -
Abbreviate the table name with the table's initials (e.g. users -> u and users_contact -> uc). -
Truncate the column name until it fits.
+
Abbreviate the table name with the table's initials (e.g. users -> u and users_contact -> uc). +
Truncate the column name until it fits.
If the constraint name is still too long, you should consider rewriting your entire data model :) -
Notes:
If you have to abbreviate the table name for one of the constraints, abbreviate it for all the constraints
If you are defining a multi column constraint, try to truncate the two column names evenly
+Notes:
If you have to abbreviate the table name for one of the constraints, abbreviate it for all the constraints
If you are defining a multi column constraint, try to truncate the two column names evenly
create table example_topics ( topic_id integer constraint example_topics_topic_id_pk @@ -52,7 +52,7 @@ constraint cne_example_id_one_line_unq unique(example_id, one_line_description) ); -
Naming primary keys might not have any obvious advantages. However, here's an example where naming the primary key really helps (and this is by no means a rare case! @@ -71,18 +71,18 @@ 3 1 INDEX (UNIQUE SCAN) OF 'EXAMPLE_TOPICS_TOPIC_ID_PK' (UNI QUE)
-Isn't it nice to see "EXAMPLE_TOPICS_TOPIC_ID_PK" in the trace +Isn't it nice to see "EXAMPLE_TOPICS_TOPIC_ID_PK" in the trace and know exactly which table oracle is using at each step? -
People disagree on whether or not we should be naming not null constraints. So, if you want to name them, please do so and follow the above naming standard. But, naming not null constraints is not a requirement.
-Though naming "not null" constraints doesn't help immeditately in error +Though naming "not null" constraints doesn't help immeditately in error debugging (e.g. the error will say something like -"Cannot insert null value into column"), we recommend naming not null +"Cannot insert null value into column"), we recommend naming not null constraints to be consistent in our naming of all constraints.
By Michael Yoon and Aurelius Prochazka
+ +By Michael Yoon and Aurelius Prochazka
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.To ensure consistency (and its collateral benefit, maintainability), we define and adhere to standards in the following areas: -
+
Usually we organize our files so that they mainly serve one of the following three purposes: -
displaying objects and their properties
manipulating or acting on objects in some way (by creating, editing, linking, etc)
housing procedures, packages, data models and other prerequisite code +
displaying objects and their properties
manipulating or acting on objects in some way (by creating, editing, linking, etc)
housing procedures, packages, data models and other prerequisite code Essentially, we want our files named in a fashion that reflects their purpose.
-Under the page root (and the template root if using the Style package): -
For naming files that enable a specific action on an object, use this format:
-
object-verb.extension
+Under the page root (and the template root if using the Style package): +
For naming files that enable a specific action on an object, use this format:
+object-verb.extension
For example, the page to erase a user's portrait from the database is -
/admin/users/portrait-erase.tcl
. -However, modules typically deal with only one primary type of object - +/admin/users/portrait-erase.tcl. +
However, modules typically deal with only one primary type of object - e.g., the Bookmarks module deals mainly with bookmarks - and so action-type files in modules don't need to be specified by the object they act on. Example: the user pages -for the Bookmarks module live in the
/bookmarks/
-directory, and so there is no need to name the bookmark editing page with a redundant url:/bookmarks/bookmark-edit.tcl
. Instead, we omit the object type, and use this convention: +for the Bookmarks module live in the /bookmarks/ +directory, and so there is no need to name the bookmark editing page with a redundant url: /bookmarks/bookmark-edit.tcl. Instead, we omit the object type, and use this convention:-
verb.extension
+verb.extension-Thus, the page to edit a bookmark is
/bookmarks/edit.tcl
. -For naming files that display the properties of a primary object - such as the bookmark object within the bookmark module - use this convention:
-
one.
extension
+Thus, the page to edit a bookmark is /bookmarks/edit.tcl. +For naming files that display the properties of a primary object - such as the bookmark object within the bookmark module - use this convention:
+one.extension
For example, the page to view one bookmark is -
/bookmarks/one.tcl
. Note that no verb is necessary for display-type files. -Otherwise, if the object to be displayed is not the primary feature of a module, simply omit the verb and use the object name:
-
object.extension
+/bookmarks/one.tcl. Note that no verb is necessary for display-type files. +Otherwise, if the object to be displayed is not the primary feature of a module, simply omit the verb and use the object name:
+object.extension
For example, the page to view the properties of an ecommerce product is -
/ecommerce/product.tcl
. -For naming files in a page flow, use the convention:
foobar.extension
(Step 1)
foobar-2.extension
(Step 2)...
foobar-N.extension
(Step N)-where
foobar
is determined by the above +/ecommerce/product.tcl. +For naming files in a page flow, use the convention:
foobar.extension (Step 1)
foobar-2.extension (Step 2)
...
foobar-N.extension (Step N)
+where foobar is determined by the above rules.
Typically, we use a three-step page flow when taking user information: -
Present a form to the user
Present a confirmation page to the user
Perform the database transaction, then redirect
Put data model files in
/www/doc/sql
, and name them +
Present a form to the user
Present a confirmation page to the user
Perform the database transaction, then redirect
Put data model files in /www/doc/sql, and name them for the modules towards which they are used:
-
module
.sql
+module.sqlIn the Tcl library directory: -
For files that contain module-specific procedures, use the +
For files that contain module-specific procedures, use the convention:
-
module
-procs.tcl
-For files that contain procedures that are part of the core ACS, +module-procs.tcl +
For files that contain procedures that are part of the core ACS, use the convention:
-
ad-
description-procs.tcl
-
File names also appear within pages, as linked URLs and
-form targets. When they do, always use abstract
-URLs (e.g., user-delete
instead of
-user-delete.tcl
), because they enhance maintainability.
+form targets. When they do, always use abstract
+URLs (e.g., user-delete instead of
+user-delete.tcl), because they enhance maintainability.
Similarly, when linking to the index page of a directory, do not
-explicitly name the index file (index.tcl
,
-index.adp
, index.html
, etc.). Instead, use
+explicitly name the index file (index.tcl,
+index.adp, index.html, etc.). Instead, use
just the directory name, for both relative links
-(subdir/
) and absolute links
-(/top-level-dir/
). If linking to the directory in which
-the page is located, use the empty string (""
), which
+(subdir/) and absolute links
+(/top-level-dir/). If linking to the directory in which
+the page is located, use the empty string (""), which
browsers will resolve correctly.
-
Include the appropriate standard header in all scripts. The first line should be a comment specifying the file path relative to the ACS root directory. e.g. -
+
# /www/index.tcl -
+
or -
+
# /tcl/module-defs.tcl -
+
For static content files (html or adp), include a CVS identification tag as a comment at the top of the file, e.g.
@@ -95,7 +95,7 @@ This can be at the top or bottom of the file.Using ad_page_contractFor non-library Tcl files (those not in the private Tcl directory), -use
ad_page_contract
+use ad_page_contract after the file path comment (this supersedes set_the_usual_form_variables and ad_return_complaint). Here is an example of using ad_page_contract, which serves both documentation and page input @@ -119,32 +119,32 @@ {persistent_cookie_p f} }
-Salient features of ad_page_contract
:
-
A mandatory documentation string is the first argument. This has -the standard form with javadoc-style @author, @cvs-id, etc, and should contain a short description of the recieved variables and any necessary explanations.
The second argument specifies the page +Salient features of ad_page_contract: +
A mandatory documentation string is the first argument. This has +the standard form with javadoc-style @author, @cvs-id, etc, and should contain a short description of the recieved variables and any necessary explanations.
The second argument specifies the page
inputs. The syntax for switches/flags (e.g. multiple-list, array,
etc.) uses a colon (:) followed by any number of flags
separated by commas (,),
-e.g. foo:integer,multiple,trim
. In particular, multiple
and
-array
are the flags that correspond to the old
-ad_page_variables
flags.
There are new flags: trim
, notnull
and
-optional
. They do what you'd expect; values will not be
+e.g. foo:integer,multiple,trim. In particular, multiple and
+array are the flags that correspond to the old
+ad_page_variables flags.
There are new flags: trim, notnull and +optional. They do what you'd expect; values will not be trimmed, unless you mark them for it; empty strings are valid input, unless you specify notnull; and a specified variable will be considered required, -unless you declare it optional.
ad_page_contract
can do validation for you: the flags integer
-and sql_identifier
will make sure that the values
-supplied are integers/sql_identifiers. The integer
flag
+unless you declare it optional.
ad_page_contract can do validation for you: the flags integer
+and sql_identifier will make sure that the values
+supplied are integers/sql_identifiers. The integer flag
will also trim leading zeros. Note that unless you specify
-notnull
, both will accept the empty string.
-
Note that ad_page_contract
does not generate
+notnull, both will accept the empty string.
+
Note that ad_page_contract does not generate QQvariables, which were automatically created by ad_page_variables and set_the_usual_form_variables. The use of bind variables makes such previous variable syntax obsolete.
-For shared Tcl library files, use ad_library
after
+For shared Tcl library files, use ad_library after
the file path comment. Its only argument is a doc_string in the
standard (javadoc-style) format, like
-ad_page_contract
. Don't forget to put the @cvs-id in
+ad_page_contract. Don't forget to put the @cvs-id in
there. Here is an example of using ad_library:
# tcl/wp-defs.tcl @@ -165,56 +165,56 @@ -- author -- created -- --- $Id$ +-- $Id$
-Of course, replace "--
" with the comment delimiter
+Of course, replace "--" with the comment delimiter
appropriate for the language in which you are programming.
-
Construct the page as one Tcl variable (name it
-page_content
), and then send it back to the browser with
-one call to doc_return
, which will call
+page_content), and then send it back to the browser with
+one call to doc_return, which will call
db_release_unused_handles prior to executing ns_return, effectively
combining the two operations.
For example:
-set page_content "[ad_header "Page Title"] +set page_content "[ad_header "Page Title"] <h2>Page Title</h2> <hr> <ul> -" +" db_foreach get_row_info { select row_information from bar } { - append page_content "<li>row_information\n" + append page_content "<li>row_information\n" } -append page_content "</ul> +append page_content "</ul> -[ad_footer]" +[ad_footer]" doc_return 200 text/html $page_content
-The old convention was to call ReturnHeaders
and
-then ns_write
for each distinct chunk of the page. This
+The old convention was to call ReturnHeaders and
+then ns_write for each distinct chunk of the page. This
approach has the disadvantage of tying up a scarce and valuable
resource (namely, a database handle) for an unpredictable amount of
time while sending packets back to the browser, and so it should be
avoided in most cases. (On the other hand, for a page that requires an
expensive database query, it's better to call
-ad_return_top_of_page
+ad_return_top_of_page
first, so that the user is not left to stare at an empty page while
the query is running.)
Local procedures (i.e., procedures defined and used only within one
-page) should be prefixed with "module_
" and
+page) should be prefixed with "module_" and
should be used rarely, only when they are exceedingly useful.
All files that prepare HTML to display should end with [ad_footer] or @@ -225,7 +225,7 @@ edit ad_header (which quite possibly can start a <table>) and ad_footer (which may need to end the table started in ad_footer) to customize the look and feel of the entire site. -
+ +
By Richard Li and Yon Feldman
OpenACS docs are written by the named authors, and may be edited @@ -11,25 +11,25 @@ our product will be useful long after the current people building and maintaining it are around. Following are some standards and guidelines that will help us achieve this goal: -+
All PL/SQL code must be well documented. We must write code that is maintainable by others, this is especially true in our case because we are building an open source toolkit than anyone can download and browse the source code. So document like you are - trying to impress your "Introduction to Programming" professor or + trying to impress your "Introduction to Programming" professor or TA. -
+
It is important to be consistent throughout an application as much as is possible given the nature of team development. This means carrying style and other conventions suchs as naming within an application, not just within one file. -
Encapsulation of related fuctionality is key to maintainability and upgradeability of our software. Try to bundle your code into - packages + packages whenever possible. This will make upgrading, bug fixing, and customizing, among other things, a possibility. -
+
When creating functions or procedures use the following template, it demonstrates most of the guidelines set forth in this document that correspond to functions and procedures: @@ -53,32 +53,32 @@ / show errors -
- Always use create or replace procedure|function
- <proc_or_func_name>
. It makes reloading packages much
+
+ Always use create or replace procedure|function + <proc_or_func_name>. It makes reloading packages much easier and painless to someone who is upgrading or fixing a bug. -
- Always qualify end
statements, i.e., the
- end
statement for a package should be end
- <package_name>;
, not just end;
; same
+
+ Always qualify end statements, i.e., the + end statement for a package should be end + <package_name>;, not just end;; same goes for procedures, functions, package bodies, and triggers. -
- Always use the "show errors" SQL*Plus command after each PL/SQL +
+ Always use the "show errors" SQL*Plus command after each PL/SQL block. It will help you debug when there are compilation errors in your PL/SQL code. -
+
Name parameters as simply as possible, i.e., use the column name if the parameter corresponds to a table column. We're deprecating the v_* and *_in syntax in favor of named parameters notation:
-+ acs_user.create(first_names => 'Jane', last_name => 'Doe', etc.) -
+ instead of -+ acs_user.create(first_names_in => 'Jane', last_name_in => 'Doe', etc.) -
+
To achieve this we must fully qualify arguements passed into @@ -107,23 +107,23 @@ / show errors -
- Explicitly designate each parameter as "in," "out," or "inout." -
+
+ Explicitly designate each parameter as "in," "out," or "inout." +
Each parameter should be on its own line, with a tab after the parameter name, then in/out/inout, then a space, and finally the datatype. -
+
Use %TYPE and %ROWTYPE whenever possible. -
- Use 't' and 'f' for booleans, not the PL/SQL "boolean" datatype +
+ Use 't' and 'f' for booleans, not the PL/SQL "boolean" datatype because it can't be used in SQL queries. -
- All new
functions (e.g., acs_object.new,
- party.new,
etc.) should optionally accept an ID:
+
+ All new functions (e.g., acs_object.new, + party.new, etc.) should optionally accept an ID:
-
+
create or replace package acs_object
as
function new (
@@ -134,22 +134,22 @@
creation_ip in acs_objects.creation_ip%TYPE default null,
context_id in acs_objects.context_id%TYPE default null
) return acs_objects.object_id%TYPE;
-
+
- takes the optional argument object_id
. Do this to
+ takes the optional argument object_id. Do this to
allow people to use the same API call when they are doing double
click protection, that is, tehy have already gotten an
- object_id
and now they want to create the object with
- that object_id
.
-
Some general style guidelines to follow for the purpose of consistency across applications. -
+
Standard indentation is 4 spaces. Our PL/SQL code is not only viewable in the SQL files but also through our SQL and PL/SQL browsers. This means that we should try to make it as consistent as possible to all source code readers. -
+
Lowercase everything, with the exception of %TYPE and %ROWTYPE.
By Ron Henderson, Revised by Joel Aufrecht
+ +By Ron Henderson, Revised by Joel Aufrecht
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.OpenACS version numbers help identify at a high-level what is in a particular release and what has changed since the last release. -
A "version number" is really just a string of the form: -
major.minor.dot[ milestone ]
A major number change indicates a fundamental change in the architecture of the system, e.g. OpenACS 3 to ACS 4. A major change is required if core backwards compatibility is broken, if upgrade is non-trivial, or if the platform changes substantially.
A minor change represents the addition of new functionality or changed UI.
A dot holds only bug fixes and security patches. Dot releases are always recommended and safe. -
A milestone marker indicates the state of the release:
d, for development, means the release is in active development and is not in its intended released form.
a, for alpha, means new development is complete and code checkins are frozen. Alpha builds should work well enough to be testable.
b, for beta, means most severe bugs are fixed and end users can start trying the release.
Release Candidate builds (rc) are believed to meet all of the criteria for release and can be installed on test instances of production systems.
Final releases have no milestone marker. (Exception: In CVS, they are tagged with -final to differentiate them from branch tags.) +
A "version number" is really just a string of the form: +
major.minor.dot[ milestone ]
A major number change indicates a fundamental change in the architecture of the system, e.g. OpenACS 3 to ACS 4. A major change is required if core backwards compatibility is broken, if upgrade is non-trivial, or if the platform changes substantially.
A minor change represents the addition of new functionality or changed UI.
A dot holds only bug fixes and security patches. Dot releases are always recommended and safe. +
A milestone marker indicates the state of the release:
d, for development, means the release is in active development and is not in its intended released form.
a, for alpha, means new development is complete and code checkins are frozen. Alpha builds should work well enough to be testable.
b, for beta, means most severe bugs are fixed and end users can start trying the release.
Release Candidate builds (rc) are believed to meet all of the criteria for release and can be installed on test instances of production systems.
Final releases have no milestone marker. (Exception: In CVS, they are tagged with -final to differentiate them from branch tags.)
Milestone markers are numbered: d1, d2, ..., a1, b1, rc1, etc.
A complete sequence of milestones between two releases:
5.0.0 5.0.0rc2 5.0.0rc1 @@ -22,7 +24,7 @@ Version numbers are also recorded in the CVS repository so that the code tree can be restored to the exact state it was in for a particular release. To translate between a distribution tar file -(acs-3.2.2.tar.gz) and a CVS tag, just swap '.' for '-'.The entire release history of the toolkit is recorded in the tags for the top-levelreadme.txt
file: +(acs-3.2.2.tar.gz) and a CVS tag, just swap '.' for '-'.The entire release history of the toolkit is recorded in the tags for the top-level readme.txt file:> cvs log readme.txt RCS file: /usr/local/cvsroot/acs/readme.txt,v @@ -58,10 +60,10 @@In the future, OpenACS packages should follow this same convention on version numbers. -
So what distinguishes an alpha release from a beta +
So what distinguishes an alpha release from a beta release? Or from a production release? We follow a specific set of rules for how OpenACS makes the transition from one state of maturity to -the next. These rules are fine-tuned with each release; an example is 5.0.0 Milestones and Milestone Criteria
+the next. These rules are fine-tuned with each release; an example is 5.0.0 Milestones and Milestone Criteria
Each package has a maturity level. Maturity level is recorded in the .info file for each major-minor release of OpenACS, and is set to the appropriate value for that release of the package.
@@ -71,24 +73,24 @@ <maturity>1</maturity> <callbacks> ... -
- Level -1: Incompatible. This package is not supported for this platform and should not be expected to work. -
- Level 0: New Submission. This is the default for packages that do not have maturity explicitly set, +
+ Level -1: Incompatible. This package is not supported for this platform and should not be expected to work. +
+ Level 0: New Submission. This is the default for packages that do not have maturity explicitly set, and for new contributions. The only criterion for level 0 is that at least one person asserts that it works on a given platform. -
- Level 1: Immature. Has no open priority 1 or priority 2 bugs. Has been installed by at least +
+ Level 1: Immature. Has no open priority 1 or priority 2 bugs. Has been installed by at least 10? different people, including 1 core developer. Has been available in a stable release for at least 1 month. Has API documentation. -
- Level 2: Mature. Same as Level 1, plus has install guide and user documentation; +
+ Level 2: Mature. Same as Level 1, plus has install guide and user documentation; no serious deviations from general coding practices; no namespace conflicts with existing level 2 packages. -
- Level 3: Mature and Standard. Same as level 2, plus meets published coding standards; +
+ Level 3: Mature and Standard. Same as level 2, plus meets published coding standards; is fully internationalized; available on both supported databases. -
Database upgrade scripts must be named very precisely in order for the Package Manager to run the correct script at the correct time.
Upgrade scripts should be named
/packages/myfirstpackage/sql/postgresql/upgrade/upgrade-OLDVERSION-NEWVERSION.sql
If the version you are working on is a later version than the current released version, OLDVERSION should be the current version. The current version is package version in the APM and in
/packages/myfirstpackage/myfirstpackage.info
. So if forums is at 2.0.1, OLDVERSION should be 2.0.1d1. Note that this means that new version development that includes an upgrade must start at d2, not d1. -If you are working on a pre-release version of a package, use the current package version as OLDVERSION. Increment the package version as appropriate (see above) and use the new version as NEWVERSION. For example, if you are working on 2.0.1d3, make it 2.0.1d4 and use
upgrade-2.0.1d3-2.0.1d4.sql
.Database upgrades should be confined to development releases, not alpha or beta releases.
- Never use a final release number as a NEWVERSION. If you do, then it is impossible to add any more database upgrades without incrementing the overall package version.
Use only the d, a, and b letters in OLDVERSION and NEWVERSION. rc is not supported by OpenACS APM.
The distance from OLDVERSION to NEWVERSION should never span a release. For example if we had a bug fix in -acs-kernel on 5.1.0 you wouldn't want a file upgrade-5.0.4-5.1.0d1.sql since if you subsequently need to provide a 5.0.4-5.0.5 upgrade you will have to rename the 5.0.4-5.1.0 upgrade since you can't have upgrades which overlap like that. Instead, use
upgrade-5.1.0d1-5.1.0d2.sql
+Database upgrade scripts must be named very precisely in order for the Package Manager to run the correct script at the correct time.
Upgrade scripts should be named /packages/myfirstpackage/sql/postgresql/upgrade/upgrade-OLDVERSION-NEWVERSION.sql
If the version you are working on is a later version than the current released version, OLDVERSION should be the current version. The current version is package version in the APM and in /packages/myfirstpackage/myfirstpackage.info. So if forums is at 2.0.1, OLDVERSION should be 2.0.1d1. Note that this means that new version development that includes an upgrade must start at d2, not d1. +
If you are working on a pre-release version of a package, use the current package version as OLDVERSION. Increment the package version as appropriate (see above) and use the new version as NEWVERSION. For example, if you are working on 2.0.1d3, make it 2.0.1d4 and use upgrade-2.0.1d3-2.0.1d4.sql.
Database upgrades should be confined to development releases, not alpha or beta releases.
+ Never use a final release number as a NEWVERSION. If you do, then it is impossible to add any more database upgrades without incrementing the overall package version.
Use only the d, a, and b letters in OLDVERSION and NEWVERSION. rc is not supported by OpenACS APM.
The distance from OLDVERSION to NEWVERSION should never span a release. For example if we had a bug fix in +acs-kernel on 5.1.0 you wouldn't want a file upgrade-5.0.4-5.1.0d1.sql since if you subsequently need to provide a 5.0.4-5.0.5 upgrade you will have to rename the 5.0.4-5.1.0 upgrade since you can't have upgrades which overlap like that. Instead, use upgrade-5.1.0d1-5.1.0d2.sql
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/eng-standards.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/eng-standards.html,v diff -u -N -r1.30 -r1.30.2.1 --- openacs-4/packages/acs-core-docs/www/eng-standards.html 11 Dec 2010 23:36:32 -0000 1.30 +++ openacs-4/packages/acs-core-docs/www/eng-standards.html 12 Jun 2011 20:03:48 -0000 1.30.2.1 @@ -1,4 +1,4 @@ - -Chapter 11. Engineering Standards Table of Contents
- OpenACS Style Guide
- + +
Chapter 9. Engineering Standards
Prev Home Next Using Form Builder: building html forms dynamically Up OpenACS Style Guide
docs@openacs.orgView comments on this page at openacs.org +- Release Version Numbering
- Constraint naming standard
- ACS File Naming and Formatting Standards
- PL/SQL Standards
- Variables
- Automated Testing
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/ext-auth-requirements.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/ext-auth-requirements.html,v diff -u -N -r1.38 -r1.38.2.1 --- openacs-4/packages/acs-core-docs/www/ext-auth-requirements.html 11 Dec 2010 23:36:32 -0000 1.38 +++ openacs-4/packages/acs-core-docs/www/ext-auth-requirements.html 12 Jun 2011 20:03:48 -0000 1.38.2.1 @@ -1,5 +1,5 @@ - -External Authentication Requirements People have plenty of usernames and passwords already, we + +
External Authentication Requirements People have plenty of usernames and passwords already, we don't want them to have yet another. We want people to be able to log in to OpenACS with the same password they use to log in to any other system.
Besides, administrators have better things to do than create @@ -8,47 +8,47 @@ log on to OpenACS, an account will automatically be created for them here.
Finally, security is increased with fewer passwords, since users generally can't remember all those passwords, so they tend to -keep them all the same and never change them.
Transparent: Users don't have to do anything special to +keep them all the same and never change them.
Transparent: Users don't have to do anything special to get an account on the local OpenACS system, if they already have an - account on the external authentication server.
Fall-back: Users who don't have an account on the + account on the external authentication server.
Fall-back: Users who don't have an account on the external authentication server are still allowed to create a local account on OpenACS. This could be for external students who should have access to .LRN, but not to the rest of the university's - resources.
Authentication Client Only: We want OpenACS to be able to + resources.
Authentication Client Only: We want OpenACS to be able to authenticate by asking some remote authority to verify the user's username/password combination. The goal is explicitly not (at this point) to have OpenACS act as an authentication server for other systems, although this could be easily added later. The goal is also not to devise an infrastructure for letting OpenACS access resources in various other systems on the user's behalf, such as IMAP, iCalendar, SMB file servers, etc., although this is - definitely an interesting use-case.
Easy configuration: We would like people to be able to + definitely an interesting use-case.
Easy configuration: We would like people to be able to configure this without having to write code. In particular, we want to build drivers that know how to talk with LDAP, RADIUS, PAM, etc., and which won't have to be locally modified. Only configuration and policies should change, code should - not.
Usability: The solution must be easy to use for end users + not.
Usability: The solution must be easy to use for end users and administrators alike. There's frequently a positive feedback effect between usability and security, because when authentication schemes have poor usability, users will think up ways to circumvent - them.
Open and modular: The design should be on the one hand + them.
Open and modular: The design should be on the one hand open to add other authentification mechanisms when needed and on the other hand very modular to enable a start with minimal requirements (driver implementations) as soon as possible.
The problem can be split into several logically separate -parts. Each has a section below.
Authority: The name of an authority trusted to authenticate - users.
Authentication Driver: An implementation of the +parts. Each has a section below.
Authority: The name of an authority trusted to authenticate + users.
Authentication Driver: An implementation of the authentication service contract, which talks to an authentication of a certain type, e.g. PAM, RADIUS, LDAP, or Active - Directory.
Authentication API: The API through which login pages and + Directory.
Authentication API: The API through which login pages and applications talk to the authentication service. There's one and only one implementation of the authentication API, namly the one - included in OpenACS Core.
Authentication Driver API: The service contract which - authentication drivers implement.
Authentication:
-
Account Management (NO PICTURE YET)
Batch Synchronization (NO PICTURE YET)
Feature Status Description New API EXT-AUTH-01 A Extend Authentication/Acct Status API EXT-AUTH-03 A Account Creation API EXT-AUTH-05 A Password Management API EXT-AUTH-30 A Authority Management API
Feature Status Description Login EXT-AUTH-04 A Rewrite login, register, and admin pages to use APIs EXT-AUTH-38 A ad_form complain feature EXT-AUTH-19 A Rewrite password recovery to use API EXT-AUTH-21 A Rewrite email verification with API EXT-AUTH-28 A Username is email switch Users will log in using a username, a authority, and a + included in OpenACS Core.
Authentication Driver API: The service contract which + authentication drivers implement.
Authentication:
+
Account Management (NO PICTURE YET)
Batch Synchronization (NO PICTURE YET)
Feature Status Description New API EXT-AUTH-01 A Extend Authentication/Acct Status API EXT-AUTH-03 A Account Creation API EXT-AUTH-05 A Password Management API EXT-AUTH-30 A Authority Management API
Feature Status Description Login EXT-AUTH-04 A Rewrite login, register, and admin pages to use APIs EXT-AUTH-38 A ad_form complain feature EXT-AUTH-19 A Rewrite password recovery to use API EXT-AUTH-21 A Rewrite email verification with API EXT-AUTH-28 A Username is email switch Users will log in using a username, a authority, and a password. The authority is the source for user/password verification. OpenACS can be an authority itself.
Each user in OpenACS will belong to exactly one authority, which -can either be the "local" OpenACS users table, in which case the +can either be the "local" OpenACS users table, in which case the password column is used, or it can be some external authority, which will be communicated with using some protocol, as implemented by an authentication driver.
Username will be separate from email address. It can be an @@ -71,11 +71,11 @@ [Forgot my password] [New user registration]
If there's only one active authority, we don't display the -authority drop-down element at all.
Feature Status Description Configuration EXT-AUTH-07 A Admin pages to control Ext-Auth parameters The site-wide systems administrator can configure the -authentication process from a page linked under /acs-admin.
Authorities - ordered list of authorities defined
Account Registration Allowed: Yes/No. Account - registration can be disabled altogether.
Registration authority - the authority in which accounts should +authority drop-down element at all.
Feature Status Description Configuration EXT-AUTH-07 A Admin pages to control Ext-Auth parameters The site-wide systems administrator can configure the +authentication process from a page linked under /acs-admin.
Authorities - ordered list of authorities defined
Account Registration Allowed: Yes/No. Account + registration can be disabled altogether.
Registration authority - the authority in which accounts should be created, using the relevant driver, if account registration is - allowed.
Username is email? - instead of asking for username, + allowed.
Username is email? - instead of asking for username, we'll ask for email. And we'll store the value in both columns, username and email. This is a setting that spans all authorities, and is primarily meant for backwards compatibility with the old OpenACS @@ -84,42 +84,42 @@ other drivers call external functions. The possible functions for each authority are split into several drivers for convenience. One driver handles authentication, one account creation, and one - changing passwords.
Feature Status Description create service contract EXT-AUTH-16 A Create service contract for Authentication EXT-AUTH-17 A Create service contract for Acct. Creation EXT-AUTH-29 A Create service contract for Passwd Management
Feature Status Description EXT-AUTH-18 A Authority configuration data model Each authority is defined like this:
Authority pretty-name, e.g. "URZ"
Authentication Driver, e.g. "RADIUS". In practice, this + changing passwords.
Feature Status Description create service contract EXT-AUTH-16 A Create service contract for Authentication EXT-AUTH-17 A Create service contract for Acct. Creation EXT-AUTH-29 A Create service contract for Passwd Management
Feature Status Description EXT-AUTH-18 A Authority configuration data model Each authority is defined like this:
Authority pretty-name, e.g. "URZ"
Authentication Driver, e.g. "RADIUS". In practice, this would be a reference to a service contract - implementation.
Authentication Driver configuration settings, e.g. host + implementation.
Authentication Driver configuration settings, e.g. host name, port, etc., as required by the particular driver. Note that this is per authority, not per driver, i.e., you can have multiple authorities with the same driver but different configuration - options.
AuthenticationAllowed - true/false, so you can disable + options.
AuthenticationAllowed - true/false, so you can disable login through some authority without having to delete the authority, and - hence also all the users who belong to that authority.
ForgottenPasswordUrl - a URL to redirect to instead of + hence also all the users who belong to that authority.
ForgottenPasswordUrl - a URL to redirect to instead of trying to use the authentication driver's password management - features.
ChangePasswordUrl - a URL to redirect to instead of + features.
ChangePasswordUrl - a URL to redirect to instead of trying to use the authentication driver's password management - features.
Account Creation Driver, e.g. "RADIUS". In practice, this + features.
Account Creation Driver, e.g. "RADIUS". In practice, this would be a reference to a service contract implementation. The reason we have separate drivers for authentication and account creation is that organizations are likely to have a home-grown - account registration process.
Account Creation Driver configuration settings, e.g. host + account registration process.
Account Creation Driver configuration settings, e.g. host name, port, etc., as required by the particular driver. Note that this is per authority, not per driver, i.e., you can have multiple authorities with the same driver but different configuration - options.
RegistrationUrl - instead of registering using OpenACS, - redirect to a certain URL site for account registration.
RegistrationAllowed - true/false, so you can disable - registration using this account.
Sort order: Preference order of - authorities.
HelpContactText: Text or HTML to be displayed + options.
RegistrationUrl - instead of registering using OpenACS, + redirect to a certain URL site for account registration.
RegistrationAllowed - true/false, so you can disable + registration using this account.
Sort order: Preference order of + authorities.
HelpContactText: Text or HTML to be displayed when user has trouble authenticating with the authority. Should include contact information such as a phone number or email.
Each authority driver will have a set of configuration options dependent on the driver, such as host, port, etc. We will need to find a mechanism for the driver to tell us which configuration options are available, a way to set these, and a way for the driver to access these settings.
OpenACS will come pre-configured with one authority, which is -the "local" authority, meaning we'll authenticate as normal using the +the "local" authority, meaning we'll authenticate as normal using the local users table. This will, just like any other authority, be -implemetned using a service contract.
Feature Status Description Synchronizing and linking users EXT-AUTH-28 A Create service contract for Batch Sync. EXT-AUTH-38 A Batch User Synchronization API EXT-AUTH-38 A IMS Synchronization driver EXT-AUTH-08 A Automation of batch Synchronization EXT-AUTH-15 B On-demand syncronization Regardless of the login method, the user needs to have a row +implemetned using a service contract.
Feature Status Description Synchronizing and linking users EXT-AUTH-28 A Create service contract for Batch Sync. EXT-AUTH-38 A Batch User Synchronization API EXT-AUTH-38 A IMS Synchronization driver EXT-AUTH-08 A Automation of batch Synchronization EXT-AUTH-15 B On-demand syncronization Regardless of the login method, the user needs to have a row in the OpenACS users table. This can happen through a batch job, in -real-time, or both in combination. We use the IMS Enterprise 1.1 specification.
Batch job means that we do a synchronization (import new +real-time, or both in combination. We use the IMS Enterprise 1.1 specification.
Batch job means that we do a synchronization (import new users, modify changed, purge deleted) on a regular interval, e.g. every night. You can also decide to have a monthly full synchronization, plus daily incremental ones. That's up to you. The @@ -130,23 +130,23 @@ be remedied by using the real-time solution. The batch job will also require error logging and an admin interface to view logs.
If an email already belongs to some other user, we log it as an error.
A user will always belong to exactly one authority, which can be -either the "local" authority or some other. Thus, the OpenACS user's -table will have to be augmented with the following columns:
Authority. Reference to the site-wide authorities list. The - authority which can authenticate this user.
Authority-specific username.
Real-time means that the first time the user logs into +either the "local" authority or some other. Thus, the OpenACS user's +table will have to be augmented with the following columns:
Authority. Reference to the site-wide authorities list. The + authority which can authenticate this user.
Authority-specific username.
Real-time means that the first time the user logs into OpenACS, we'll query the authority that authenticated him for information about this user. That authentication authority will then give us at least first names, last name and email. The pros and cons are the opposite of batch jobs. Using both in combination -is ideal.
Note: One solution to the "two users from different authorities -have the same email" problem above would be to allow users to +is ideal.
Note: One solution to the "two users from different authorities +have the same email" problem above would be to allow users to belong to multiple authorities. Then we would notice that the email already exists, ask the user if he thinks he's the same person, and if so, ask him to prove so by authenticating using the other authority. Thus he'll have just authenticated in two different authorities, and we can record that this is the same person. We'd still have a problem if there was an email conflict between two accounts on the same authority. Hm. I don't think it's worth spending too much -time trying to solve this problem through software.
Feature Status Description EXT-AUTH-31 EXT-AUTH-31 A Upgrade user data model for ext-auth After having authenticated using the relevant authority driver, +time trying to solve this problem through software.
Feature Status Description EXT-AUTH-31 EXT-AUTH-31 A Upgrade user data model for ext-auth After having authenticated using the relevant authority driver, we'll look for the username/authority pair in the users table.
If we don't find any, that means that we're either not doing batch synchronizing, or that the user has been added since the last sync. In that case, we'll try to do a real-time synchronization, if @@ -155,60 +155,60 @@ create a row in the local users table using that information.
If that doesn't work, we'll tell the user that their account isn't yet available, and the driver will supply a message for us, -which could say "The account should be available tomorrow. If not, -contact X."
If a user doesn't have an account, the site-wide +which could say "The account should be available tomorrow. If not, +contact X."
If a user doesn't have an account, the site-wide configuration can allow the user to register for one, as defined in the configuration discussed above. This section is about normal account registration through a authority driver.
The account creation service contract implementation will -need to tell us which information to ask the user for:
Required Fields: A list of fields which are - required.
Optional Fields: A list of fields which are - optional.
The fields to choose from are these:
Username
First names
Last name
URL
Password
Secret question
Secret answer
It should return the following:
Creation status (OK, Try-Again, Fail)
Creation message: What went wrong, or a welcome - message.
Account status: Is the account ready for use?
User information: first_names, last_name, email, url, +need to tell us which information to ask the user for:
Required Fields: A list of fields which are + required.
Optional Fields: A list of fields which are + optional.
The fields to choose from are these:
Username
First names
Last name
URL
Password
Secret question
Secret answer
It should return the following:
Creation status (OK, Try-Again, Fail)
Creation message: What went wrong, or a welcome + message.
Account status: Is the account ready for use?
User information: first_names, last_name, email, url, password, password_hash, secret_question, secret_answer. The driver only needs to return the columns which were changed or added - through the registration process. Typically, only the "local" + through the registration process. Typically, only the "local" driver will return password and secret question/answer.
After creating the remote account, a local account is created with the information gathered through the form/returned by the driver.
By default, a local account creation implementation is provided, which will create a new OpenACS user, and, in addition to the default local account creation above, also store the password -in hashed form.
Password management is about changing password, retrieving password, and resetting password.
It's up to the authority driver implementation to decide whether to support any or all of these features, and to say so using the CanXXX methods (see driver API below).
Additionally, the authority can be configured with a URL to redirect to in the case of forgotten passwords, or when the user -desires to change password.
Feature Status Description EXT-AUTH-20 EXT-AUTH-20 A Login over HTTPS Login pages must be able to be sent over a secure connection +desires to change password.
Feature Status Description EXT-AUTH-20 EXT-AUTH-20 A Login over HTTPS Login pages must be able to be sent over a secure connection (https), so your password won't get sent over the wire in cleartext, while leaving the rest of the site non-secure (http). I believe that this requires some (minor) changes to the current -session handling code.
Email verification needs to be handled both at registration +session handling code.
Email verification needs to be handled both at registration and at login.
In both cases, it'll be handled by the driver sending automatically sending the email containing a link for the user to verify his account. Then the driver will return an account status -of "closed,temporary", and a message that says "Check your inbox -and click the link in the email".
OpenACS will have a page which receives the email +of "closed,temporary", and a message that says "Check your inbox +and click the link in the email".
OpenACS will have a page which receives the email verification, for use by local accounts. Other authorities will have to implement their own page, most likely on the authority's -own server.
There are a number of items which touch on external authentication and session management. And even though they're not directly linked to external authentication, I would recommend that we handle a number of them, either because they're important for security, or because it makes sense to fix them while we're messing -with this part of the codebase anyway.
Feature Status Description EXT-AUTH-33 EXT-AUTH-33 A Untrusted Logins I like the idea of having multiple login levels:
Not logged in
Untrusted login: We'll show you un-sensitive personal +with this part of the codebase anyway.
Feature Status Description EXT-AUTH-33 EXT-AUTH-33 A Untrusted Logins I like the idea of having multiple login levels:
Not logged in
Untrusted login: We'll show you un-sensitive personal content, but won't let you modify anything or see personal data. A normal login becomes untrusted after a certain amount of time, and the user will have to re-enter his/her password in order to gain access to personal data. Untrusted login never expires, unless explicitly done so through either changing password or clicking a - special "expire all logins" link.
Normal login: The user is logged, and has type his + special "expire all logins" link.
Normal login: The user is logged, and has type his password sufficiently recently that we trust the login. All normal operations are allowed. Will degrade to untrusted login after a - specified amount of time.
Secure login: The user is logged in over a secure + specified amount of time.
Secure login: The user is logged in over a secure connection (HTTPS), potentially even using a special secure password. This would be for sensitive actions, such as credit card transactions.
There are two advantages to this. First, when people's login @@ -224,19 +224,19 @@ example, we could let you browse publically available forums, and only when you want to post do you need to log in. This makes it even more feasible to have a more secure login expiration -setting.
By default,
auth::require_login
would +setting.By default, auth::require_login would bounce to the login page if the user is only logged in at the untrusted level. Only if you explicitly say -
auth::require_login -untrusted
will we give you +auth::require_login -untrusted will we give you the user_id of a user who's only logged in in untrusted -mode.Similarly,
ad_conn user_id
will continue +mode.Similarly, ad_conn user_id will continue to return 0 (not logged in) when the user is only logged in -untrusted, and we'll supply another variable,
ad_conn -untrusted_user_id
, which wlll be set to the user_id for +untrusted, and we'll supply another variable, ad_conn +untrusted_user_id, which wlll be set to the user_id for all login levels.This should ensure that we get full access to the new feature, while leaving all current code just as secure as it was -before.
Feature Status Description EXT-AUTH-34 EXT-AUTH-34 A Expire Logins Currently, OpenACS is unusable in practice without persistent +before.
Feature Status Description EXT-AUTH-34 EXT-AUTH-34 A Expire Logins Currently, OpenACS is unusable in practice without persistent login. The login will expire after just a few minutes of inactivity, and you'll get bounced to the login page where you have to enter both email and password again. Unacceptable in @@ -247,15 +247,15 @@ login expire after a period of inactivity, but the amount of time should be configurable and default to something reasonable like an hour or so.
This will require looking into and changing the design of the -current session handling code.
Feature Status Description EXT-AUTH-23 EXT-AUTH-23 Single sign-on Instead of redirecting to the login page, auth::require_login +current session handling code.
Feature Status Description EXT-AUTH-23 EXT-AUTH-23 Single sign-on Instead of redirecting to the login page, auth::require_login can redirect to an authentication server, which can redirect back to a page that logs the user in. This should be very easy to implement.
Alternatively, if you want to combine this with fallback to OpenACS accounts, we would instead present the normal login screen, -but put a button which says "Login using X", where X is the -redirection-based external authority.
Feature Status Description EXT-AUTH-22 EXT-AUTH-22 B rewrite cookie handling Currently, if you've ever left a permanent login cookie on +but put a button which says "Login using X", where X is the +redirection-based external authority.
Feature Status Description EXT-AUTH-22 EXT-AUTH-22 B rewrite cookie handling Currently, if you've ever left a permanent login cookie on someone elses machine, that person will be forever logged in until he/she explicitly logs out. You can change your password, you can do anything you want, but unless a logout is requested from that @@ -270,32 +270,32 @@ void. Of course, we don't want to incur a DB hit on every request, so we'll need to cache the secret token, or only check it when refreshing the session cookie, which, I believe, normally happens -every 10 minutes or so.
Feature Status Description EXT-AUTH-24 EXT-AUTH-24 A Email on password change As an additional security measure, we should email the +every 10 minutes or so.
Feature Status Description EXT-AUTH-24 EXT-AUTH-24 A Email on password change As an additional security measure, we should email the account's email address whenever the password is changed, so that -he/she is at least alerted to the fact.
Feature Status Description EXT-AUTH-25 EXT-AUTH-25 A Implement password policy Again, to increase security, we should add password policies, +he/she is at least alerted to the fact.
Feature Status Description EXT-AUTH-25 EXT-AUTH-25 A Implement password policy Again, to increase security, we should add password policies, such as passwords needing to be changed after a certain number of days, change on next login (after a new random password has been generated), or requiring that the password satisfies certain complexity rules, i.e. both upper and lowercase characters, numbers, special chars, etc.
It would good to extend the current maximum password length -from 10 to at least 32 characters.
Feature Status Description EXT-AUTH-26 EXT-AUTH-26 B Login without explicit domain In order to make it easier for people, we've been toying with -the idea of a functionality like this:
If the user enters "foobar@ix.urz.uni-heidelberg.de", it - is translated to mean username = "foobar", authority = - "ix.urz.uni-heidelberg.de".
If the user enters "foobar", it's recognized to not +from 10 to at least 32 characters.
Feature Status Description EXT-AUTH-26 EXT-AUTH-26 B Login without explicit domain In order to make it easier for people, we've been toying with +the idea of a functionality like this:
If the user enters "foobar@ix.urz.uni-heidelberg.de", it + is translated to mean username = "foobar", authority = + "ix.urz.uni-heidelberg.de".
If the user enters "foobar", it's recognized to not include any authority, and the default authority of - "ix.urz.uni-heidelberg.de" is used.
If the user enters "foo@bar.com", it's recognized as not + "ix.urz.uni-heidelberg.de" is used.
If the user enters "foo@bar.com", it's recognized as not belonging to any known authority, and as such, it's translated to mean - username = "foo@bar.com", authority = "local".
If this is deemed desirable, a way to implement this would be -through these settings:
Split: A regexp which will split the user's entry into - username and authority parts. For example "^([^@]+)(@[^@]+)?$". An + username = "foo@bar.com", authority = "local".
If this is deemed desirable, a way to implement this would be +through these settings:
Split: A regexp which will split the user's entry into + username and authority parts. For example "^([^@]+)(@[^@]+)?$". An easier to use but less flexible method would be that you simply - specify a certain character to split by, such as "@" or "\". If the + specify a certain character to split by, such as "@" or "\". If the regexp doesn't match, or in the latter case, if there's more than one occurrence of the specified character sequence, the split will - fail, signaling that the user's entry was not valid.
Default authority: The default authority will be the first one + fail, signaling that the user's entry was not valid.
Default authority: The default authority will be the first one in the sort order.
The relevant code in user-login.tcl would look like this:
if { ![auth::split_username -username_var username -authority_var authority] } { @@ -305,7 +305,7 @@ # username will now contain username # authority will now contain authority -
Feature Status Description EXT-AUTH-27 EXT-AUTH-27 B Who's online list While we're touching the session handling code, anyway, it +
Feature Status Description EXT-AUTH-27 EXT-AUTH-27 B Who's online list While we're touching the session handling code, anyway, it would be nice to add a feature to show who's currently online, a nice real-time collaboration feature frequently requested by members of the community. This is particularly interesting when @@ -314,18 +314,18 @@ which authenticated users have requested pags on the site in the last x minutes (typically about 5), and thus are considered to be currently online. There's nothing more to it. This lets us display -a list of "active users" somewhere on the site, and make their name +a list of "active users" somewhere on the site, and make their name a link to a real-time chat service like Jabber.
We've already made the changes necessary to security-procs.tcl to do this on an earlier project, but haven't -quite finished the work and put it back into the tree.
Feature Status Description EXT-AUTH-28 EXT-AUTH-28 implement subsite-level config If we want to, we could let subsite administrators configure +quite finished the work and put it back into the tree.
Feature Status Description EXT-AUTH-28 EXT-AUTH-28 implement subsite-level config If we want to, we could let subsite administrators configure the login process for that particular subsite. This would probably only entail letting the subsite admin leave out certain authorities defined site-wide, and change the sort order.
I think we should leave this out until we have a use case for -it, someone who'd need it.
Feature Status Description EXT-AUTH-32 EXT-AUTH-32 A Parameters for Service Contract Implementation EXT-AUTH-35 A Make the Authentication API a service contract For completely free-form authentication logic and mechanisms, +it, someone who'd need it.
Feature Status Description EXT-AUTH-32 EXT-AUTH-32 A Parameters for Service Contract Implementation EXT-AUTH-35 A Make the Authentication API a service contract For completely free-form authentication logic and mechanisms, something like Andrew Grumet's -Pluggable +Pluggable Authentication for OACS Draft is interesting. He's proposing a scheme where the entire user interaction is encapsulated in, and left entirely to, a service contract. This @@ -334,10 +334,10 @@ people are going to want to use a username/password-based scheme, and having easy configuration through a web UI is more important than total flexibility at this point.
Besides, we can always do this in the future, by letting the -public Authentication API (
auth::require_login
-andauth::authenticate
) be implemented through a -service contract.
Feature Status Description EXT-AUTH-36 EXT-AUTH-36 A Authenticate against multiple servers Both OKI and OpenACS supports a form of stacking, where you +public Authentication API (auth::require_login +and auth::authenticate) be implemented through a +service contract.
Feature Status Description EXT-AUTH-36 EXT-AUTH-36 A Authenticate against multiple servers Both OKI and OpenACS supports a form of stacking, where you can be logged into multiple authorities at the same time. This is useful if, for example, you need to get login tokens such as Kerberos tickets for access to shared resources.
I can see the value in this, but for simplicity's sake, I'm @@ -350,30 +350,30 @@ for user/group data and access control lists, SMB for file storage, etc. But at the moment, we don't have any users of such things that are ready. We have some who are on the steps, but let's wait till -they're there.
Feature Status Description Implement specific drivers EXT-AUTH-09 A Create Auth. drivers for Local Authority EXT-AUTH-10 A Create Acct. Creation driver for Local Authority EXT-AUTH-11 A Create Auth. driver for PAM EXT-AUTH-12 X Create Acct. Creation driver for PAM - this - functionality is explicitly excluded from PAM EXT-AUTH-13 A Create Acct. Creation driver for LDAP EXT-AUTH-14 A Create Auth. driver for LDAP We'll need drivers for:
Operating system (Linux/Solaris) PAM: Delegate to the +they're there.
Feature Status Description Implement specific drivers EXT-AUTH-09 A Create Auth. drivers for Local Authority EXT-AUTH-10 A Create Acct. Creation driver for Local Authority EXT-AUTH-11 A Create Auth. driver for PAM EXT-AUTH-12 X Create Acct. Creation driver for PAM - this + functionality is explicitly excluded from PAM EXT-AUTH-13 A Create Acct. Creation driver for LDAP EXT-AUTH-14 A Create Auth. driver for LDAP We'll need drivers for:
Operating system (Linux/Solaris) PAM: Delegate to the operating system, which can then talk to RADIUS, LDAP, whatever. This is convenient because there'll be plenty of drivers for the OS PAM level, so we don't have to write them all ourselves. The downside is that we can't do things like account creation, password management, real-time account synchronization, etc., not supported by PAM (I'm not entirely sure what is and is not - supported).
RADIUS
LDAP
RADIUS is a simple username/password-type authentication server.
It also supports sending a challenge to which the user must respond with the proper answer (e.g. mother's maiden name, or could be additional password), but we will not support this feature.
A RADIUS client -implementation +implementation in Python can be found in the -exUserFolder +exUserFolder module for Zope -(documentation).
We'd really appreciate feedback on this proposal. Please +(documentation).
We'd really appreciate feedback on this proposal. Please follow up at -this -openacs.org forums thread.
Threads -and links collected by Carl Blesius.
Draft -Proposal by Andrew Grumet.
Threads +and links collected by Carl Blesius.
Draft +Proposal by Andrew Grumet.
Yale CAS, a centrl authentication service a' la - Passport.
View comments on this page at openacs.org + Passport.View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/filename.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/filename.html,v diff -u -N -r1.46 -r1.46.2.1 --- openacs-4/packages/acs-core-docs/www/filename.html 17 Oct 2010 21:06:07 -0000 1.46 +++ openacs-4/packages/acs-core-docs/www/filename.html 12 Jun 2011 20:03:48 -0000 1.46.2.1 @@ -1,5 +1,5 @@ -Detailed Design Documentation Template By You
+
Detailed Design Documentation Template By You
NOTE: Some of the sections of this template may not apply to your package, e.g. there may be no user-visible UI elements for a component of the OpenACS Core. Furthermore, it may be easier in some circumstances Index: openacs-4/packages/acs-core-docs/www/for-everyone.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/for-everyone.html,v diff -u -N -r1.26 -r1.26.2.1 --- openacs-4/packages/acs-core-docs/www/for-everyone.html 11 Dec 2010 23:36:32 -0000 1.26 +++ openacs-4/packages/acs-core-docs/www/for-everyone.html 12 Jun 2011 20:03:48 -0000 1.26.2.1 @@ -1,2 +1,2 @@ - -
Part I. OpenACS For Everyone
Prev Home Next OpenACS Core Documentation Up Chapter 1. High level information: What is OpenACS?
docs@openacs.orgView comments on this page at openacs.org + +Part I. OpenACS For Everyone Table of Contents
Prev Home Next OpenACS Core Documentation Up Chapter 1. High level information: What is OpenACS?
docs@openacs.orgView comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/general-documents.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/general-documents.html,v diff -u -N -r1.26 -r1.26.2.1 --- openacs-4/packages/acs-core-docs/www/general-documents.html 11 Dec 2010 23:36:32 -0000 1.26 +++ openacs-4/packages/acs-core-docs/www/general-documents.html 12 Jun 2011 20:03:48 -0000 1.26.2.1 @@ -1,2 +1,2 @@ - -Chapter 1. High level information: What is OpenACS? Table of Contents
View comments on this page at openacs.org + +Chapter 1. High level information: What is OpenACS? Table of Contents
View comments on this page at openacs.org Index: openacs-4/packages/acs-core-docs/www/groups-design.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/groups-design.html,v diff -u -N -r1.32 -r1.32.2.1 --- openacs-4/packages/acs-core-docs/www/groups-design.html 11 Dec 2010 23:36:32 -0000 1.32 +++ openacs-4/packages/acs-core-docs/www/groups-design.html 12 Jun 2011 20:03:48 -0000 1.32.2.1 @@ -1,32 +1,32 @@ - -Groups Design By Rafael H. Schloming and Mark Thomas
+ +Groups Design By Rafael H. Schloming and Mark Thomas
OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff. -
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
ER diagram
Transaction flow diagram
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
ER diagram
Transaction flow diagram
Almost all database-backed websites have users, and need to model the grouping of users. The OpenACS 4 Parties and Groups system is intended to provide the flexibility needed to model complex real-world organizational structures, particularly to support powerful subsite services; that is, where one OpenACS installation can support what appears to the user as distinct web services -for different user communities.
The primary limitation of the OpenACS 3.x user group system is that it -restricts the application developer to representing a "flat group" -that contains only users: The
user_groups
table may contain the -group_id
of a parent group, but parent-child relationship +for different user communities.The primary limitation of the OpenACS 3.x user group system is that it +restricts the application developer to representing a "flat group" +that contains only users: The user_groups table may contain the +group_id of a parent group, but parent-child relationship support is limited because it only allows one kind of relationship between groups to be represented. Moreover, the Oracle database's limited support for tree-like structures makes the queries over these relationships expensive.
In addition, the Module Scoping design in OpenACS 3.0 introduced a party abstraction - a thing that is a person or a group of people - though not in the form of an explicit table. Rather, the triple of -
scope
,user_id
, andgroup_id
columns +scope, user_id, and group_id columns was used to identify the party. One disadvantage of this design convention is that it increases a data model's complexity by requiring the programmer -to:
add these three columns to each "scoped" table
define a multi-column check constraint to protect against data corruption -(e.g., a row with a
scope
value of "group" but a null -group_id
)perform extra checks in
Tcl
andPL/SQL
-functions and procedures to check both theuser_id
and -group_id
valuesThe core of the Group Systems data model is quite simple, but it was -designed in the hopes of modeling "real world" organizations which +to:
add these three columns to each "scoped" table
define a multi-column check constraint to protect against data corruption +(e.g., a row with a scope value of "group" but a null +group_id)
perform extra checks in Tcl and PL/SQL +functions and procedures to check both the user_id and +group_id values
The core of the Group Systems data model is quite simple, but it was +designed in the hopes of modeling "real world" organizations which can be complex graph structures. The Groups System only considers groups that can be modeled using directed acyclic graphs, but queries over these structures are still complex enough to slow the system down. Since almost @@ -38,44 +38,44 @@ without making the system too complex or too slow. The added triggers, views, and tables and will increase storage requirements and the insert and delete times in an effort to speed access time. The limited flexibility (no updates -on membership) trades against the complexity of the code.
The Group System data model consists of the following tables:
parties
+on membership) trades against the complexity of the code.The Group System data model consists of the following tables:
- parties
The set of all defined parties: any person, user, or -group must have a corresponding row in this table.
persons
+group must have a corresponding row in this table.- persons
The set of all defined persons. To allow easy sorting of persons, the -name requirement 30.10 is met by -splitting the person's name into two columns:
first_names
and -last_name
.users
+name requirement 30.10 is met by +splitting the person's name into two columns: first_names and +last_name.- users
The set of all registered users; this table includes information about -the user's email address and the user's visits to the site.
user_preferences
+the user's email address and the user's visits to the site.- user_preferences -
Preferences for the user.
groups
+Preferences for the user.
- groups -
The set of all defined groups.
group_types
+The set of all defined groups.
- group_types
When a new type of group is created, this table holds additional -knowledge level attributes for the group and its subtypes.
membership_rels
+knowledge level attributes for the group and its subtypes.- membership_rels
The set of direct membership relationships between a group and a -party.
group_member_index
+party.- group_member_index -
A mapping of a party P to the groups -{Gi}the party is a member of; this mapping -includes the type of relationship by including the appropriate
rel_id
-from themembership_rels
table.composition_rels
+A mapping of a party P to the groups +{Gi}the party is a member of; this mapping +includes the type of relationship by including the appropriaterel_id +from the membership_rels table.
- composition_rels
The set of direct component relationships between a group and another -group.
group_component_index
+group.- group_component_index -
A mapping of a group Gto the set of groups -{Gi} that G is a component of; +
A mapping of a group Gto the set of groups +{Gi} that G is a component of; this mapping includes the type of relationship by including the -appropriate
rel_id
from thecomposition_rels
table.New groups are created through the
group.new
constructor. +appropriaterel_id from the composition_rels table.New groups are created through the group.new constructor. When a specialized type of group is required, the group type can be extended by an application developer. Membership constraints can be specified at -creation time by passing a parent group to the constructor.
The
membership_rels
andcomposition_rels
tables indicate +creation time by passing a parent group to the constructor.The membership_rels and composition_rels tables indicate a group's direct members and direct components; these tables do not provide a record of the members or components that are in the group by virtue of being a member or component of one of the group's component groups. @@ -85,60 +85,60 @@ queries responsive, the data model includes triggers (described in the next paragraph) which watch for changes in membership or composition and update tables that maintain the group party mappings, i.e., -
group_member_index
andgroup_component_index
. One can think -of these tables as a manually maintained index.The following triggers keep the
group_*_index
tables up to -date:
membership_rels_in_tr
+group_member_index and group_component_index. One can think +of these tables as a manually maintained index.The following triggers keep the group_*_index tables up to +date:
- membership_rels_in_tr
Is executed when a new group/member relationship is created (an insert on -
membership_rels
)membership_rels_del_tr
+membership_rels)- membership_rels_del_tr
Is executed when a group/member relationship is deleted (a delete on -
membership_rels
)composition_rels_in_tr
+membership_rels)- composition_rels_in_tr
Is executed when a new group/component relationship is created (an insert -on
composition_rels
)composition_rels_del_tr
+on composition_rels)- composition_rels_del_tr
Is executed when a group/component relationship is deleted (a delete on -
composition_rels
)The data model provides the following views onto the -
group_member_index
andgroup_component_index
tables. No -code outside of Groups System should modify thegroup_*_index
-tables.
group_member_map
+composition_rels)The data model provides the following views onto the +group_member_index and group_component_index tables. No +code outside of Groups System should modify the group_*_index +tables.
- group_member_map
A mapping of a party to the groups the party is a member of; this mapping -includes the type of relationship by including the appropriate
rel_id
-from themembership_rels
table.group_approved_member_map
+includes the type of relationship by including the appropriaterel_id +from the membership_rels table.- group_approved_member_map
A mapping of a party to the groups the party is an approved member of -(
member_state
is 'approved'); this mapping includes the type -of relationship by including the appropriaterel_id
from the -membership_rels
table.group_distinct_member_map
+(member_state is 'approved'); this mapping includes the type +of relationship by including the appropriaterel_id from the +membership_rels table.- group_distinct_member_map
A person may appear in the group member map multiple times, for example, by being a member of two different groups that are both components of a third -group. This view is strictly a mapping of approved members -to groups.
group_component_map
+group. This view is strictly a mapping of approved members +to groups.- group_component_map -
A mapping of a group Gto the set of groups -{Gi} group G is a component of; +
A mapping of a group Gto the set of groups +{Gi} group G is a component of; this mapping includes the type of relationship by including the -appropriate
rel_id
from thecomposition_rels
table.party_member_map
+appropriaterel_id from the composition_rels table.- party_member_map -
A mapping of a party P to the set of parties -{Pi} party P is a member -of.
party_approved_member_map
+A mapping of a party P to the set of parties +{Pi} party P is a member +of.
- party_approved_member_map -
A mapping of a party P to the set of parties -{Pi} party P is an -approved member of.
The API consists of tables and views and PL/SQL functions. -
The
group_types
table is used to create new types of groups.The
group_member_map
,group_approved_member_map
, -group_distinct_member_map
,group_component_map
, -party_member_map
, andparty_approved_member_map
views are -used to query group membership and composition.Person
person.new
creates a new person and returns the -person_id
. The function must be given the full name of the person in -two pieces:first_names
andlast_name
. All other fields are -optional and default to null except forobject_type
which defaults -to person andcreation_date
which defaults tosysdate
. The +The group_types table is used to create new types of groups.
The group_member_map, group_approved_member_map, +group_distinct_member_map, group_component_map, +party_member_map, and party_approved_member_map views are +used to query group membership and composition.
Person
person.new creates a new person and returns the +person_id. The function must be given the full name of the person in +two pieces: first_names and last_name. All other fields are +optional and default to null except for object_type which defaults +to person and creation_date which defaults to sysdate. The interface for this function is:
function person.new ( person_id persons.person_id%TYPE, @@ -151,19 +151,19 @@ first_names persons.first_names%TYPE, last_name persons.last_name%TYPE ) return persons.person_id%TYPE; -
person.delete
deletes the person whoseperson_id
is +person.delete deletes the person whose person_id is passed to it. The interface for this procedure is:
procedure person.delete ( person_id persons.person_id%TYPE ); -
person.name
returns the name of the person whose -person_id
is passed to it. The interface for this function is:+person.name returns the name of the person whose +person_id is passed to it. The interface for this function is:
function person.name ( person_id persons.person_id%TYPE ) return varchar; -User
acs_user.new
creates a new user and returns theuser_id
. +User
acs_user.new creates a new user and returns the user_id. The function must be given the user's email address and the full name of -the user in two pieces:
first_names
andlast_name
. All +the user in two pieces: first_names and last_name. All other fields are optional. The interface for this function is:function acs_user.new ( user_id users.user_id%TYPE, @@ -182,19 +182,19 @@ screen_name users.screen_name%TYPE, email_verified_p users.email_verified_p%TYPE ) return users.user_id%TYPE; -
acs_user.delete
deletes the user whoseuser_id
is passed +acs_user.delete deletes the user whose user_id is passed to it. The interface for this procedure is:
procedure acs_user.delete ( user_id users.user_id%TYPE ); -
acs_user.receives_alerts_p
returns 't' if the user should +acs_user.receives_alerts_p returns 't' if the user should receive email alerts and 'f' otherwise. The interface for this function is:
function acs_user.receives_alerts_p ( user_id users.user_id%TYPE ) return varchar; -Use the procedures
acs_user.approve_email
and -acs_user.unapprove_email
to specify whether the user's email +Use the procedures acs_user.approve_email and +acs_user.unapprove_email to specify whether the user's email address is valid. The interface for these procedures are:
procedure acs_user.approve_email ( user_id users.user_id%TYPE @@ -203,11 +203,11 @@ procedure acs_user.unapprove_email ( user_id users.user_id%TYPE ); -Group
acs_group.new
creates a new group and returns the -group_id
. All fields are optional and default to null except for -object_type
which defaults to 'group', -creation_date
which defaults tosysdate
, and -group_name
which is required. The interface for +Group
acs_group.new creates a new group and returns the +group_id. All fields are optional and default to null except for +object_type which defaults to 'group', +creation_date which defaults to sysdate, and +group_name which is required. The interface for this function is:
function acs_group.new ( group_id groups.group_id%TYPE, @@ -219,21 +219,21 @@ url parties.url%TYPE, group_name groups.group_name%TYPE ) return groups.group_id%TYPE; -
acs_group.name
returns the name of the group whose -group_id
is passed to it. The interface for this function is:+acs_group.name returns the name of the group whose +group_id is passed to it. The interface for this function is:
function acs_group.name ( group_id groups.group_id%TYPE ) return varchar; -
acs_group.member_p
returns 't' if the specified party is +acs_group.member_p returns 't' if the specified party is a member of the specified group. Returns 'f' otherwise. The interface for this function is:
function acs_group.member_p ( group_id groups.group_id%TYPE, party_id parties.party_id%TYPE, ) return char; -Membership Relationship
membership_rel.new
creates a new membership relationship type -between two parties and returns the relationship type'srel_id
. -All fields are optional and default to null except forrel_type
+Membership Relationship
membership_rel.new creates a new membership relationship type +between two parties and returns the relationship type's rel_id. +All fields are optional and default to null except for rel_type which defaults to membership_rel. The interface for this function is:
function membership_rel.new ( rel_id membership_rels.rel_id%TYPE, @@ -244,42 +244,42 @@ creation_user acs_objects.creation_user%TYPE, creation_ip acs_objects.creation_ip%TYPE, ) return membership_rels.rel_id%TYPE; -
membership_rel.ban
sets themember_state
of the given -rel_id
to 'banned'. The interface for this procedure is:+membership_rel.ban sets the member_state of the given +rel_id to 'banned'. The interface for this procedure is:
procedure membership_rel.ban ( rel_id membership_rels.rel_id%TYPE ); -
membership_rel.approve
sets themember_state
of the -givenrel_id
to 'approved'. The interface for this procedure +membership_rel.approve sets the member_state of the +given rel_id to 'approved'. The interface for this procedure is:
procedure membership_rel.approve ( rel_id membership_rels.rel_id%TYPE ); -
membership_rel.reject
sets themember_state
of the given -rel_id
to 'rejected. The interface for this procedure is:+membership_rel.reject sets the member_state of the given +rel_id to 'rejected. The interface for this procedure is:
procedure membership_rel.reject ( rel_id membership_rels.rel_id%TYPE ); -
membership_rel.unapprove
sets themember_state
of the -givenrel_id
to an empty string ''. The interface for this +membership_rel.unapprove sets the member_state of the +given rel_id to an empty string ''. The interface for this procedure is:
procedure membership_rel.unapprove ( rel_id membership_rels.rel_id%TYPE ); -
membership_rel.deleted
sets themember_state
of the -givenrel_id
to 'deleted'. The interface for this procedure +membership_rel.deleted sets the member_state of the +given rel_id to 'deleted'. The interface for this procedure is:
procedure membership_rel.deleted ( rel_id membership_rels.rel_id%TYPE ); -
membership_rel.delete
deletes the givenrel_id
. The +membership_rel.delete deletes the given rel_id. The interface for this procedure is:
procedure membership_rel.delete ( rel_id membership_rels.rel_id%TYPE ); -Composition Relationship
composition_rel.new
creates a new composition relationship type -and returns the relationship'srel_id
. All fields are optional -and default to null except forrel_type
which defaults to +Composition Relationship
composition_rel.new creates a new composition relationship type +and returns the relationship's rel_id. All fields are optional +and default to null except for rel_type which defaults to composition_rel. The interface for this function is:
function membership_rel.new ( rel_id composition_rels.rel_id%TYPE, @@ -289,18 +289,18 @@ creation_user acs_objects.creation_user%TYPE, creation_ip acs_objects.creation_ip%TYPE, ) return composition_rels.rel_id%TYPE; -
composition_rel.delete
deletes the givenrel_id
. The +composition_rel.delete deletes the given rel_id. The interface for this procedure is:
procedure membership_rel.delete ( rel_id composition_rels.rel_id%TYPE ); -
- System creator -
- System owner +
- System owner -
- Documentation author +
- Documentation author -
Mark Thomas