About half way through switching cocanwiki to using the new PG interface.
authorrich <rich>
Mon, 27 Mar 2006 16:43:43 +0000 (16:43 +0000)
committerrich <rich>
Mon, 27 Mar 2006 16:43:43 +0000 (16:43 +0000)
Should have started this before migrating the web server, but you
live & learn.

23 files changed:
Makefile.config
scripts/.depend
scripts/Makefile
scripts/lib/cocanwiki.ml
scripts/lib/cocanwiki_create_host.ml
scripts/lib/cocanwiki_create_host.mli
scripts/lib/cocanwiki_date.ml
scripts/lib/cocanwiki_diff.ml
scripts/lib/cocanwiki_diff.mli
scripts/lib/cocanwiki_emailnotify.ml
scripts/lib/cocanwiki_ext_calendar.ml
scripts/lib/cocanwiki_links.ml
scripts/lib/cocanwiki_links.mli
scripts/lib/cocanwiki_mail.ml
scripts/lib/cocanwiki_mail.mli
scripts/lib/cocanwiki_pages.ml
scripts/lib/cocanwiki_pages.mli
scripts/lib/cocanwiki_server_settings.ml
scripts/lib/cocanwiki_strings.ml
scripts/lib/cocanwiki_template.ml
scripts/lib/cocanwiki_template.mli
scripts/lib/wikilib.ml
scripts/lib/wikilib.mli

index 24a30bc..a66049f 100644 (file)
@@ -1,7 +1,7 @@
-# $Id: Makefile.config,v 1.29 2005/12/05 10:07:44 rich Exp $
+# $Id: Makefile.config,v 1.30 2006/03/27 16:43:43 rich Exp $
 
 PACKAGE := cocanwiki
-VERSION := 1.3.20
+VERSION := 1.4.0
 
 # Normally ignored.  However, if you are installing centrally (using
 # 'make pkg-install'), then the components are installed in the
@@ -11,3 +11,9 @@ VERSION := 1.3.20
 APACHECONFDIR := /etc/apache
 
 WIKIINSTALLDIR := /usr/share/cocanwiki
+
+# Location of PG'OCaml (http://merjis.com/developers/pgocaml)
+PGOCAMLDIR := $(HOME)/d/merjis/freeware/pgocaml
+
+# Location of the OCaml lib directory.
+OCAMLLIBDIR := $(shell ocamlc -where)
\ No newline at end of file
index 48529fd..cec4d43 100644 (file)
-lib/cocanwiki.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-lib/cocanwiki.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
 lib/cocanwiki_create_host.cmo: lib/cocanwiki_create_host.cmi 
 lib/cocanwiki_create_host.cmx: lib/cocanwiki_create_host.cmi 
-lib/cocanwiki_diff.cmo: lib/cocanwiki.cmo lib/cocanwiki_files.cmo \
+lib/cocanwiki_diff.cmo: lib/cocanwiki_files.cmo lib/cocanwiki.cmo \
     lib/cocanwiki_diff.cmi 
-lib/cocanwiki_diff.cmx: lib/cocanwiki.cmx lib/cocanwiki_files.cmx \
+lib/cocanwiki_diff.cmx: lib/cocanwiki_files.cmx lib/cocanwiki.cmx \
     lib/cocanwiki_diff.cmi 
 lib/cocanwiki_emailnotify.cmo: lib/cocanwiki.cmo 
 lib/cocanwiki_emailnotify.cmx: lib/cocanwiki.cmx 
-lib/cocanwiki_ext_calendar.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-lib/cocanwiki_ext_calendar.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-lib/cocanwiki_images.cmo: lib/cocanwiki_files.cmo lib/cocanwiki_strings.cmo \
+lib/cocanwiki_ext_calendar.cmo: lib/cocanwiki_template.cmi \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+lib/cocanwiki_ext_calendar.cmx: lib/cocanwiki_template.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+lib/cocanwiki_images.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_files.cmo \
     lib/cocanwiki_images.cmi 
-lib/cocanwiki_images.cmx: lib/cocanwiki_files.cmx lib/cocanwiki_strings.cmx \
+lib/cocanwiki_images.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_files.cmx \
     lib/cocanwiki_images.cmi 
-lib/cocanwiki_links.cmo: lib/cocanwiki.cmo lib/wikilib.cmi \
+lib/cocanwiki_links.cmo: lib/wikilib.cmi lib/cocanwiki.cmo \
     lib/cocanwiki_links.cmi 
-lib/cocanwiki_links.cmx: lib/cocanwiki.cmx lib/wikilib.cmx \
+lib/cocanwiki_links.cmx: lib/wikilib.cmx lib/cocanwiki.cmx \
     lib/cocanwiki_links.cmi 
-lib/cocanwiki_mail.cmo: lib/cocanwiki_date.cmo lib/cocanwiki_pages.cmi \
-    lib/cocanwiki_template.cmi lib/wikilib.cmi lib/cocanwiki_mail.cmi 
-lib/cocanwiki_mail.cmx: lib/cocanwiki_date.cmx lib/cocanwiki_pages.cmx \
-    lib/cocanwiki_template.cmx lib/wikilib.cmx lib/cocanwiki_mail.cmi 
+lib/cocanwiki_mail.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_pages.cmi lib/cocanwiki_date.cmo lib/cocanwiki_mail.cmi 
+lib/cocanwiki_mail.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_pages.cmx lib/cocanwiki_date.cmx lib/cocanwiki_mail.cmi 
+lib/cocanwiki.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo 
+lib/cocanwiki.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx 
 lib/cocanwiki_ok.cmo: lib/cocanwiki_template.cmi 
 lib/cocanwiki_ok.cmx: lib/cocanwiki_template.cmx 
-lib/cocanwiki_pages.cmo: lib/cocanwiki.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_strings.cmo lib/wikilib.cmi lib/cocanwiki_pages.cmi 
-lib/cocanwiki_pages.cmx: lib/cocanwiki.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_strings.cmx lib/wikilib.cmx lib/cocanwiki_pages.cmi 
-lib/cocanwiki_template.cmo: lib/cocanwiki_files.cmo lib/cocanwiki_strings.cmo \
-    lib/cocanwiki_version.cmo lib/cocanwiki_template.cmi 
-lib/cocanwiki_template.cmx: lib/cocanwiki_files.cmx lib/cocanwiki_strings.cmx \
-    lib/cocanwiki_version.cmx lib/cocanwiki_template.cmi 
+lib/cocanwiki_pages.cmo: lib/wikilib.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_links.cmi lib/cocanwiki.cmo lib/cocanwiki_pages.cmi 
+lib/cocanwiki_pages.cmx: lib/wikilib.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_links.cmx lib/cocanwiki.cmx lib/cocanwiki_pages.cmi 
+lib/cocanwiki_template.cmo: lib/cocanwiki_version.cmo \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_files.cmo \
+    lib/cocanwiki_template.cmi 
+lib/cocanwiki_template.cmx: lib/cocanwiki_version.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_files.cmx \
+    lib/cocanwiki_template.cmi 
 lib/wikilib.cmo: lib/cocanwiki_strings.cmo lib/wikilib.cmi 
 lib/wikilib.cmx: lib/cocanwiki_strings.cmx lib/wikilib.cmi 
 lib/cocanwiki_mail.cmi: lib/cocanwiki.cmo 
 lib/cocanwiki_pages.cmi: lib/cocanwiki.cmo 
-broken_links.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-broken_links.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-change_password.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-change_password.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-change_password_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-change_password_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-contact.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-contact.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-contact_show.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-contact_show.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-contacts.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-contacts.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-crash.cmo: lib/cocanwiki.cmo lib/cocanwiki_server_settings.cmo \
-    lib/cocanwiki_template.cmi 
-crash.cmx: lib/cocanwiki.cmx lib/cocanwiki_server_settings.cmx \
-    lib/cocanwiki_template.cmx 
-create_contact.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-create_contact.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-create_contact_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-create_contact_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-create_user.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-create_user.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-create_user_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-create_user_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-dead_ends.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-dead_ends.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-delete_contact.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-delete_contact.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-delete_contact_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-delete_contact_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-delete_file.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_ok.cmo 
-delete_file.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_ok.cmx 
-delete_file_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-delete_file_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-delete_image.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_ok.cmo 
-delete_image.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_ok.cmx 
-delete_image_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-delete_image_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-delete_user.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-delete_user.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-delete_user_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-delete_user_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-diff.cmo: lib/cocanwiki.cmo lib/cocanwiki_diff.cmi lib/cocanwiki_template.cmi 
-diff.cmx: lib/cocanwiki.cmx lib/cocanwiki_diff.cmx lib/cocanwiki_template.cmx 
-edit.cmo: lib/cocanwiki.cmo lib/cocanwiki_diff.cmi \
-    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_pages.cmi lib/cocanwiki_strings.cmo \
-    lib/cocanwiki_template.cmi lib/wikilib.cmi 
-edit.cmx: lib/cocanwiki.cmx lib/cocanwiki_diff.cmx \
-    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_pages.cmx lib/cocanwiki_strings.cmx \
-    lib/cocanwiki_template.cmx lib/wikilib.cmx 
-edit_contact.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-edit_contact.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-edit_contact_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-edit_contact_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-edit_file.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-edit_file.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
-edit_file_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-edit_file_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-edit_host_css.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-edit_host_css.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-edit_host_css_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-edit_host_css_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-edit_host_settings.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-edit_host_settings.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-edit_host_settings_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-edit_host_settings_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-edit_image.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-edit_image.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
-edit_image_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-edit_image_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-edit_page_css.cmo: lib/cocanwiki.cmo lib/cocanwiki_diff.cmi \
-    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-edit_page_css.cmx: lib/cocanwiki.cmx lib/cocanwiki_diff.cmx \
-    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-edit_page_css_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-edit_page_css_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-edit_sitemenu.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-edit_sitemenu.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-edit_user.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-edit_user.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-edit_user_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-edit_user_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-email_change.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-email_change.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
+broken_links.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+broken_links.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+change_password_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+change_password_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+change_password.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+change_password.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+contact.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+contact.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+contact_show.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+contact_show.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+contacts.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+contacts.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+crash.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_server_settings.cmo \
+    lib/cocanwiki.cmo 
+crash.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_server_settings.cmx \
+    lib/cocanwiki.cmx 
+create_contact_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+create_contact_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+create_contact.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+create_contact.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+create_user_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+create_user_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+create_user.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+create_user.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+dead_ends.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+dead_ends.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+delete_contact_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+delete_contact_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+delete_contact.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+delete_contact.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+delete_file_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+delete_file_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+delete_file.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki_emailnotify.cmo \
+    lib/cocanwiki.cmo 
+delete_file.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki_emailnotify.cmx \
+    lib/cocanwiki.cmx 
+delete_image_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+delete_image_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+delete_image.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki_emailnotify.cmo \
+    lib/cocanwiki.cmo 
+delete_image.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki_emailnotify.cmx \
+    lib/cocanwiki.cmx 
+delete_user_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+delete_user_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+delete_user.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+delete_user.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+diff.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_diff.cmi lib/cocanwiki.cmo 
+diff.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_diff.cmx lib/cocanwiki.cmx 
+edit_contact_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+edit_contact_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+edit_contact.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+edit_contact.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+edit_file_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+edit_file_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+edit_file.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+edit_file.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+edit_host_css_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+edit_host_css_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+edit_host_css.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+edit_host_css.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+edit_host_settings_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+edit_host_settings_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+edit_host_settings.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+edit_host_settings.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+edit_image_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+edit_image_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+edit_image.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+edit_image.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+edit.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_pages.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_diff.cmi lib/cocanwiki.cmo 
+edit.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_pages.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_diff.cmx lib/cocanwiki.cmx 
+edit_page_css_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+edit_page_css_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+edit_page_css.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_diff.cmi lib/cocanwiki.cmo 
+edit_page_css.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_diff.cmx lib/cocanwiki.cmx 
+edit_sitemenu.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+edit_sitemenu.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+edit_user_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+edit_user_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+edit_user.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+edit_user.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+email_change.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+email_change.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
 file.cmo: lib/cocanwiki.cmo 
 file.cmx: lib/cocanwiki.cmx 
-files.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-files.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-forgot_password.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-forgot_password.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-forgot_password_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-forgot_password_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-history.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-history.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-history_rss.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-history_rss.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-host_menu.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-host_menu.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-hoststyle.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-hoststyle.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
+files.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+files.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+forgot_password_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+forgot_password_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+forgot_password.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+forgot_password.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+history.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+history.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+history_rss.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+history_rss.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+host_menu.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+host_menu.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+hoststyle.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+hoststyle.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
 image.cmo: lib/cocanwiki.cmo 
 image.cmx: lib/cocanwiki.cmx 
-images.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-images.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-invite_user.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-invite_user.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-invite_user_confirm.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-invite_user_confirm.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-invite_user_confirm_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-invite_user_confirm_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-invite_user_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-invite_user_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-largest_pages.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-largest_pages.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-links.cmo: lib/cocanwiki.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_template.cmi 
-links.cmx: lib/cocanwiki.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_template.cmx 
-login.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-login.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-login_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_strings.cmo \
-    lib/cocanwiki_template.cmi 
-login_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_strings.cmx \
-    lib/cocanwiki_template.cmx 
-logout.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-logout.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-mail_import.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_mail.cmi lib/cocanwiki_ok.cmo lib/cocanwiki_pages.cmi \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi lib/wikilib.cmi 
-mail_import.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_mail.cmx lib/cocanwiki_ok.cmx lib/cocanwiki_pages.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx lib/wikilib.cmx 
-mail_import_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-mail_import_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-mail_rebuild.cmo: lib/cocanwiki.cmo lib/cocanwiki_mail.cmi \
-    lib/cocanwiki_ok.cmo 
-mail_rebuild.cmx: lib/cocanwiki.cmx lib/cocanwiki_mail.cmx \
-    lib/cocanwiki_ok.cmx 
-mailing_list_confirm.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-mailing_list_confirm.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-mailing_list_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-mailing_list_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-mailing_list_send.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-mailing_list_send.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-mailing_list_unsubscribe.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-mailing_list_unsubscribe.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-mailing_list_view.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-mailing_list_view.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-new_page_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-new_page_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-orphans.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-orphans.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-page.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_server_settings.cmo \
-    lib/cocanwiki_template.cmi lib/wikilib.cmi 
-page.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_server_settings.cmx \
-    lib/cocanwiki_template.cmx lib/wikilib.cmx 
-page_email_confirm.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-page_email_confirm.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-page_email_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-page_email_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-page_email_send.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-page_email_send.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-page_email_unsubscribe.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-page_email_unsubscribe.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-page_rss.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi lib/wikilib.cmi 
-page_rss.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx lib/wikilib.cmx 
+images.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+images.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+invite_user_confirm_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+invite_user_confirm_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+invite_user_confirm.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+invite_user_confirm.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+invite_user_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+invite_user_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+invite_user.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+invite_user.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+largest_pages.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+largest_pages.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+links.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_links.cmi \
+    lib/cocanwiki.cmo 
+links.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_links.cmx \
+    lib/cocanwiki.cmx 
+login_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki.cmo 
+login_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki.cmx 
+login.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+login.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+logout.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+logout.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+mail_import_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+mail_import_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+mail_import.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_pages.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_mail.cmi lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+mail_import.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_pages.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_mail.cmx lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+mailing_list_confirm.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+mailing_list_confirm.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+mailing_list_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+mailing_list_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+mailing_list_send.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+mailing_list_send.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+mailing_list_unsubscribe.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+mailing_list_unsubscribe.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+mailing_list_view.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+mailing_list_view.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+mail_rebuild.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki_mail.cmi \
+    lib/cocanwiki.cmo 
+mail_rebuild.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki_mail.cmx \
+    lib/cocanwiki.cmx 
+new_page_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+new_page_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+orphans.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+orphans.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+page_email_confirm.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+page_email_confirm.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+page_email_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+page_email_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+page_email_send.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+page_email_send.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+page_email_unsubscribe.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+page_email_unsubscribe.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+page.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_server_settings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_links.cmi lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+page.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_server_settings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_links.cmx lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+page_rss.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+page_rss.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
 pagestyle.cmo: lib/cocanwiki.cmo 
 pagestyle.cmx: lib/cocanwiki.cmx 
-preview.cmo: lib/cocanwiki.cmo lib/wikilib.cmi 
-preview.cmx: lib/cocanwiki.cmx lib/wikilib.cmx 
-rebuild_links.cmo: lib/cocanwiki.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_template.cmi 
-rebuild_links.cmx: lib/cocanwiki.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_template.cmx 
-recent.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-recent.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-recent_rss.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-recent_rss.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-recently_visited.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-recently_visited.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-rename_page.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_pages.cmi lib/cocanwiki_strings.cmo lib/wikilib.cmi 
-rename_page.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_pages.cmx lib/cocanwiki_strings.cmx lib/wikilib.cmx 
-rename_page_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-rename_page_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-restore.cmo: lib/cocanwiki.cmo lib/cocanwiki_diff.cmi \
-    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_ok.cmo 
-restore.cmx: lib/cocanwiki.cmx lib/cocanwiki_diff.cmx \
-    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_ok.cmx 
-restore_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_diff.cmi \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_template.cmi 
-restore_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_diff.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_template.cmx 
-search.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi lib/wikilib.cmi 
-search.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx lib/wikilib.cmx 
-send_feedback.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-send_feedback.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-send_feedback_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-send_feedback_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-set_password.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo 
-set_password.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx 
-set_password_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-set_password_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-signup.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-signup.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
-sitemap.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi lib/wikilib.cmi 
-sitemap.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx lib/wikilib.cmx 
-source.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo lib/cocanwiki_pages.cmi 
-source.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx lib/cocanwiki_pages.cmx 
-stats.cmo: lib/cocanwiki.cmo lib/cocanwiki_server_settings.cmo \
-    lib/cocanwiki_template.cmi 
-stats.cmx: lib/cocanwiki.cmx lib/cocanwiki_server_settings.cmx \
-    lib/cocanwiki_template.cmx 
-stats_top.cmo: lib/cocanwiki.cmo lib/cocanwiki_server_settings.cmo \
-    lib/cocanwiki_template.cmi 
-stats_top.cmx: lib/cocanwiki.cmx lib/cocanwiki_server_settings.cmx \
-    lib/cocanwiki_template.cmx 
-undelete_file.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-undelete_file.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-undelete_file_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-undelete_file_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-undelete_image.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_template.cmi 
-undelete_image.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_template.cmx 
-undelete_image_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-undelete_image_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-upload_file.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_images.cmi lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo \
-    lib/cocanwiki_template.cmi 
-upload_file.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_images.cmx lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx \
-    lib/cocanwiki_template.cmx 
-upload_file_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-upload_file_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-upload_image.cmo: lib/cocanwiki.cmo lib/cocanwiki_emailnotify.cmo \
-    lib/cocanwiki_images.cmi lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-upload_image.cmx: lib/cocanwiki.cmx lib/cocanwiki_emailnotify.cmx \
-    lib/cocanwiki_images.cmx lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
-upload_image_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-upload_image_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-user_prefs.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo lib/cocanwiki_template.cmi 
-user_prefs.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx lib/cocanwiki_template.cmx 
-user_prefs_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-user_prefs_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-users.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-users.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-what_links_here.cmo: lib/cocanwiki.cmo lib/cocanwiki_links.cmi \
-    lib/cocanwiki_template.cmi 
-what_links_here.cmx: lib/cocanwiki.cmx lib/cocanwiki_links.cmx \
-    lib/cocanwiki_template.cmx 
-admin/admin.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-admin/admin.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
-admin/create_host.cmo: lib/cocanwiki.cmo lib/cocanwiki_create_host.cmi \
-    lib/cocanwiki_ok.cmo lib/cocanwiki_strings.cmo 
-admin/create_host.cmx: lib/cocanwiki.cmx lib/cocanwiki_create_host.cmx \
-    lib/cocanwiki_ok.cmx lib/cocanwiki_strings.cmx 
-admin/create_host_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-admin/create_host_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-admin/edit_host_css.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-admin/edit_host_css.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-admin/edit_host_css_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-admin/edit_host_css_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-admin/edit_hostnames.cmo: lib/cocanwiki.cmo lib/cocanwiki_ok.cmo \
-    lib/cocanwiki_strings.cmo 
-admin/edit_hostnames.cmx: lib/cocanwiki.cmx lib/cocanwiki_ok.cmx \
-    lib/cocanwiki_strings.cmx 
-admin/edit_hostnames_form.cmo: lib/cocanwiki.cmo lib/cocanwiki_template.cmi 
-admin/edit_hostnames_form.cmx: lib/cocanwiki.cmx lib/cocanwiki_template.cmx 
-admin/host.cmo: lib/cocanwiki.cmo lib/cocanwiki_date.cmo \
-    lib/cocanwiki_template.cmi 
-admin/host.cmx: lib/cocanwiki.cmx lib/cocanwiki_date.cmx \
-    lib/cocanwiki_template.cmx 
+preview.cmo: lib/wikilib.cmi lib/cocanwiki.cmo 
+preview.cmx: lib/wikilib.cmx lib/cocanwiki.cmx 
+rebuild_links.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_links.cmi \
+    lib/cocanwiki.cmo 
+rebuild_links.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_links.cmx \
+    lib/cocanwiki.cmx 
+recently_visited.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+recently_visited.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+recent.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+recent.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+recent_rss.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+recent_rss.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+rename_page_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+rename_page_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+rename_page.cmo: lib/wikilib.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_pages.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+rename_page.cmx: lib/wikilib.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_pages.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+restore_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_diff.cmi lib/cocanwiki.cmo 
+restore_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_diff.cmx lib/cocanwiki.cmx 
+restore.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki_links.cmi \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki_diff.cmi lib/cocanwiki.cmo 
+restore.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki_links.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki_diff.cmx lib/cocanwiki.cmx 
+search.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+search.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+send_feedback_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+send_feedback_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+send_feedback.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+send_feedback.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+set_password_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+set_password_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+set_password.cmo: lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+set_password.cmx: lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+signup.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+signup.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+sitemap.cmo: lib/wikilib.cmi lib/cocanwiki_template.cmi \
+    lib/cocanwiki_strings.cmo lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+sitemap.cmx: lib/wikilib.cmx lib/cocanwiki_template.cmx \
+    lib/cocanwiki_strings.cmx lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+sitemap_xml.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_date.cmo lib/cocanwiki.cmo 
+sitemap_xml.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_date.cmx lib/cocanwiki.cmx 
+source.cmo: lib/cocanwiki_pages.cmi lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+source.cmx: lib/cocanwiki_pages.cmx lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+stats.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_server_settings.cmo \
+    lib/cocanwiki.cmo 
+stats.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_server_settings.cmx \
+    lib/cocanwiki.cmx 
+stats_top.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_server_settings.cmo \
+    lib/cocanwiki.cmo 
+stats_top.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_server_settings.cmx \
+    lib/cocanwiki.cmx 
+undelete_file_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+undelete_file_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+undelete_file.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+undelete_file.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+undelete_image_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+undelete_image_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+undelete_image.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+undelete_image.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+upload_file_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+upload_file_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+upload_file.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki_images.cmi \
+    lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+upload_file.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki_images.cmx \
+    lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+upload_image_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+upload_image_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+upload_image.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_images.cmi lib/cocanwiki_emailnotify.cmo lib/cocanwiki.cmo 
+upload_image.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_images.cmx lib/cocanwiki_emailnotify.cmx lib/cocanwiki.cmx 
+user_prefs_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+user_prefs_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+user_prefs.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_strings.cmo \
+    lib/cocanwiki_ok.cmo lib/cocanwiki.cmo 
+user_prefs.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_strings.cmx \
+    lib/cocanwiki_ok.cmx lib/cocanwiki.cmx 
+users.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+users.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+what_links_here.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_links.cmi \
+    lib/cocanwiki.cmo 
+what_links_here.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_links.cmx \
+    lib/cocanwiki.cmx 
+admin/admin.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+admin/admin.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
+admin/create_host_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+admin/create_host_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+admin/create_host.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki_create_host.cmi lib/cocanwiki.cmo 
+admin/create_host.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki_create_host.cmx lib/cocanwiki.cmx 
+admin/edit_host_css_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+admin/edit_host_css_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+admin/edit_host_css.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+admin/edit_host_css.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+admin/edit_hostnames_form.cmo: lib/cocanwiki_template.cmi lib/cocanwiki.cmo 
+admin/edit_hostnames_form.cmx: lib/cocanwiki_template.cmx lib/cocanwiki.cmx 
+admin/edit_hostnames.cmo: lib/cocanwiki_strings.cmo lib/cocanwiki_ok.cmo \
+    lib/cocanwiki.cmo 
+admin/edit_hostnames.cmx: lib/cocanwiki_strings.cmx lib/cocanwiki_ok.cmx \
+    lib/cocanwiki.cmx 
+admin/host.cmo: lib/cocanwiki_template.cmi lib/cocanwiki_date.cmo \
+    lib/cocanwiki.cmo 
+admin/host.cmx: lib/cocanwiki_template.cmx lib/cocanwiki_date.cmx \
+    lib/cocanwiki.cmx 
index d77b120..c9adce3 100644 (file)
@@ -1,33 +1,68 @@
 # Makefile for COCANWIKI.
-# $Id: Makefile,v 1.46 2005/04/02 17:30:54 rich Exp $
+# $Id: Makefile,v 1.47 2006/03/27 16:43:44 rich Exp $
 
 include ../Makefile.config
 
+PGOCAML_PP := camlp4o -I +pcre -I +extlib -I $(PGOCAMLDIR) $(OCAMLLIBDIR)/unix.cma $(OCAMLLIBDIR)/pcre/pcre.cma $(OCAMLLIBDIR)/extlib/extLib.cma $(OCAMLLIBDIR)/calendar/calendar.cma pgocaml.cma pa_pgsql.cmo
+
 OCAMLC := ocamlc
-OCAMLCFLAGS := -w s \
-       -I +apache -I +pcre -I +dbi -I +extlib -I +netstring -I +calendar \
-       -I lib
+OCAMLCFLAGS := \
+       -package apache,pcre,extlib,netstring,calendar -I $(PGOCAMLDIR) \
+       -I lib -pp "$(PGOCAML_PP)"
 CPP := cpp
 
+export PGDATABASE=cocanwiki
+
+ifeq ($(shell hostname),oirase)
+# While compiling on home machine, create a tunnel using
+# ssh -L 5431:localhost:5432 towada.merjis.com
+export PGHOST=localhost
+export PGPORT=5431
+endif
+
 SRCS := $(wildcard *.ml)
 ADMIN_SRCS := $(wildcard admin/*.ml)
 
 OBJS := $(SRCS:.ml=.cmo)
 ADMIN_OBJS := $(ADMIN_SRCS:.ml=.cmo)
 
-LIB_OBJS := lib/cocanwiki_version.cmo \
-       $(patsubst %,lib/%,$(shell cd lib && ocamldsort -byte *.ml *.mli))
+# NB. Order in which these are built really matters!  To rebuild
+# the ordering after substantially editing the library files, try:
+# PGDATABASE=cocanwiki ocamldsort -pp "'$(PGOCAML_PP)'" -byte *.ml *.mli
+LIB_OBJS := \
+       lib/cocanwiki_version.cmo \
+       lib/cocanwiki_date.cmo \
+       lib/cocanwiki_files.cmo \
+       lib/cocanwiki_server_settings.cmo \
+       lib/cocanwiki_strings.cmo \
+       lib/cocanwiki_version.cmo \
+       lib/cocanwiki_create_host.cmo \
+       lib/wikilib.cmo \
+       lib/cocanwiki_template.cmo \
+       lib/cocanwiki_images.cmo \
+       lib/cocanwiki_ok.cmo \
+       lib/cocanwiki.cmo \
+       lib/cocanwiki_links.cmo \
+       lib/cocanwiki_ext_calendar.cmo \
+       lib/cocanwiki_emailnotify.cmo \
+       lib/cocanwiki_diff.cmo \
+       lib/cocanwiki_pages.cmo \
+       lib/cocanwiki_mail.cmo
 
 INSTDIR := ../html/_bin
 
 all: lib/cocanwiki.cma $(OBJS) $(ADMIN_OBJS)
 
 lib/cocanwiki.cma: $(LIB_OBJS)
-       $(OCAMLC) $(OCAMLCFLAGS) -a -o $@ $^
+       ocamlfind ocamlc $(OCAMLCFLAGS) -a -o $@ $^
 
 lib/cocanwiki_version.ml: lib/cocanwiki_version.ml.in ../Makefile.config
        $(CPP) -P -DPACKAGE="$(PACKAGE)" -DVERSION="$(VERSION)" $< > $@
 
+# For debugging camlp4 macro.
+print:
+       $(PGOCAML_PP) pr_o.cmo lib/cocanwiki_pages.ml
+
 clean:
        rm -f *~ *.bak core *.cmi *.cmo *.cma lib/cocanwiki_version.ml
        rm -f lib/*~ lib/*.bak lib/core lib/*.cmi lib/*.cmo lib/*.cma
@@ -42,16 +77,18 @@ install:
        install -c -m 0555 $(ADMIN_OBJS) $(INSTDIR)/admin
 
 %.cmi: %.mli
-       $(OCAMLC) $(OCAMLCFLAGS) -c $<
+       ocamlfind ocamlc $(OCAMLCFLAGS) -c $<
 
 %.cmo: %.ml
-       $(OCAMLC) $(OCAMLCFLAGS) -c $<
+       ocamlfind ocamlc $(OCAMLCFLAGS) -c $<
 
 dep:    .depend
 depend: .depend
 
 .depend:
-       ocamldep -I lib lib/*.ml lib/*.mli *.ml admin/*.ml > $@
+       ocamldep -pp "$(PGOCAML_PP)" \
+         -I lib \
+         lib/*.ml lib/*.mli *.ml admin/*.ml > $@
 
 ifeq ($(wildcard .depend),.depend)
 include .depend
index b4f6c20..d1f8ec6 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki.ml,v 1.8 2005/11/24 14:54:15 rich Exp $
+ * $Id: cocanwiki.ml,v 1.9 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,13 +27,6 @@ open Printf
 open Cocanwiki_ok
 open Cocanwiki_strings
 
-module Pool = DbiPool (Dbi_postgresql)
-
-(* This function is used to grab a database handle.  It's used in a couple
- * of very special places, and is not for general consumption.
- *)
-let _get_dbh r = Pool.get r "cocanwiki"
-
 (* The "host object". *)
 type host_t = { hostname : string;
                canonical_hostname : string;
@@ -57,7 +50,7 @@ type prefs_t = {
 
 (* The "user object". *)
 type user_t = Anonymous                        (* Not logged in. *)
-           | User of int * string * permissions_t list * prefs_t
+           | User of int32 * string * permissions_t list * prefs_t
                                        (* Userid, name, perms, prefs. *)
 
 let test_permission {edit_anon = edit_anon; view_anon = view_anon} perm user =
@@ -97,172 +90,182 @@ let register_script ?(restrict = []) ?(anonymous = true) run =
   register_script
     (fun r ->
        let q = new cgi r in
-       let dbh = _get_dbh r in
-
-       (* Get the host ID, by comparing the Host: header with the hostnames
-       * table in the database.
-       *)
-       let hostid, hostname, canonical_hostname, edit_anon, view_anon =
-        let hostname = try Request.hostname r
-        with Not_found ->
-          error ~back_button:true
-            ~title:"Browser problem" dbh (-1) q
-            ("Your browser didn't send a \"Host\" header as part of " ^
-             "the HTTP request.  Unfortunately this web server cannot " ^
-             "handle HTTP requests without a \"Host\" header.");
-          return () in
-        let hostname = String.lowercase hostname in
 
-        let sth =
-          dbh#prepare_cached
-            "select h.id, h.canonical_hostname, h.edit_anon, h.view_anon
-                from hostnames hn, hosts h
-               where hn.name = ? and hn.hostid = h.id" in
-        sth#execute [`String hostname];
+       (* XXX Database pooling. *)
+       let dbh = PGOCaml.connect ~database:"cocanwiki" () in
+       PGOCaml.begin_work dbh;
 
+       let exn =
         try
-          (match sth#fetch1 () with
-               [ `Int id; `String canonical_hostname;
-                 `Bool edit_anon; `Bool view_anon ] ->
-                 id, hostname, canonical_hostname, edit_anon, view_anon
-             | _ -> assert false)
-        with
-            Not_found ->
+          (* Get the host ID, by comparing the Host: header with the hostnames
+           * table in the database.
+           *)
+          let hostid, hostname, canonical_hostname, edit_anon, view_anon =
+            let hostname = try Request.hostname r
+            with Not_found ->
               error ~back_button:true
-                ~title:"Unknown website" dbh (-1) q
+                ~title:"Browser problem" dbh (-1l) q
+                ("Your browser didn't send a \"Host\" header as part of " ^
+                   "the HTTP request.  Unfortunately this web server cannot "^
+                   "handle HTTP requests without a \"Host\" header.");
+              return () in
+            let hostname = String.lowercase hostname in
+
+            let rows =
+              PGSQL(dbh)
+                "select h.id, h.canonical_hostname, h.edit_anon, h.view_anon
+                    from hostnames hn, hosts h
+                   where hn.name = $hostname and hn.hostid = h.id" in
+
+            match rows with
+            | [id, canonical_hostname, edit_anon, view_anon] ->
+                id, hostname, canonical_hostname, edit_anon, view_anon
+            | [] ->
+              error ~back_button:true
+                ~title:"Unknown website" dbh (-1l) q
                 ("No website called \"" ^ hostname ^ "\" can be found.  " ^
                  "If you are the administrator of this site, check that " ^
                  "the hostname is listed in the \"hostnames\" table " ^
                  "in the database.");
-              return () in
+                return ()
+            | _ -> assert false in
 
-       (* Create the host object. *)
-       let host = { hostname = hostname;
-                   canonical_hostname = canonical_hostname;
-                   edit_anon = edit_anon;
-                   view_anon = view_anon } in
+          (* Create the host object. *)
+          let host = { hostname = hostname;
+                       canonical_hostname = canonical_hostname;
+                       edit_anon = edit_anon;
+                       view_anon = view_anon } in
 
-       (* Look for the user's cookie, and determine from this the user
-       * object.
-       *)
-       let user =
-        try
-          let cookie =
-            (* Allow the user to deliberately specify an extra "cookie"
-             * parameter, which we will send back as a cookie.  This is
-             * useful for "mail my password"-type scripts.
-             *)
-            if q#param_exists "cookie" then (
-              let value = q#param "cookie" in
-              let cookie = Cookie.cookie "auth" value ~path:"/" in
-              Table.set (Request.headers_out r) "Set-Cookie" cookie#to_string;
-              value
-            ) else (
-              (* Normal cookie, from the headers. *)
-              let header = Table.get (Request.headers_in r) "Cookie" in
-              let cookies = Cookie.parse header in
+          (* Look for the user's cookie, and determine from this the user
+           * object.
+           *)
+          let user =
+            try
               let cookie =
-                List.find (fun cookie -> cookie#name = "auth") cookies in
-              cookie#value
-            ) in
-
-          let sth =
-            dbh#prepare_cached
-              "select u.id, u.name, u.can_edit, u.can_manage_users,
-                       u.can_manage_contacts, u.can_manage_site,
-                       u.can_edit_global_css, u.can_import_mail,
-                       u.email, u.email_notify
-                  from usercookies uc, users u
-                 where uc.cookie = ? and uc.userid = u.id and u.hostid = ?" in
-          sth#execute [`String cookie; `Int hostid];
-          (match sth#fetch1 () with
-               [ `Int userid; `String name;
-                 `Bool can_edit; `Bool can_manage_users;
-                 `Bool can_manage_contacts; `Bool can_manage_site;
-                 `Bool can_edit_global_css; `Bool can_import_mail;
-                 (`Null | `String _) as email; `Bool email_notify ] ->
-                 (* Every logged in user can view. *)
-                 let perms = [CanView] in
-                 let perms =
-                   if can_edit then CanEdit :: perms
-                   else perms in
-                 let perms =
-                   if can_manage_users then CanManageUsers :: perms
-                   else perms in
-                 let perms =
-                   if can_manage_contacts then CanManageContacts :: perms
-                   else perms in
-                 let perms =
-                   if can_manage_site then CanManageSite :: perms
-                   else perms in
-                 let perms =
-                   if can_edit_global_css then CanEditGlobalCSS :: perms
-                   else perms in
-                 let perms =
-                   if can_import_mail then CanImportMail :: perms
-                   else perms in
-                 (* Preferences. *)
-                 let email =
-                   match email with
-                       `Null -> None
-                     | `String email -> Some email in
-                 let prefs = { email = email;
-                               email_notify = email_notify; } in
-                 User (userid, name, perms, prefs)
-             | _ -> assert false)
-        with
-            Not_found -> Anonymous
-       in
+                (* Allow the user to deliberately specify an extra "cookie"
+                 * parameter, which we will send back as a cookie.  This is
+                 * useful for "mail my password"-type scripts.
+                 *)
+                if q#param_exists "cookie" then (
+                  let value = q#param "cookie" in
+                  let cookie = Cookie.cookie "auth" value ~path:"/" in
+                  Table.set (Request.headers_out r)
+                    "Set-Cookie" cookie#to_string;
+                  value
+                ) else (
+                  (* Normal cookie, from the headers. *)
+                  let header = Table.get (Request.headers_in r) "Cookie" in
+                  let cookies = Cookie.parse header in
+                  let cookie =
+                    List.find (fun cookie -> cookie#name = "auth") cookies in
+                  cookie#value
+                ) in
 
-       (* If the ~restrict parameter is given, then we want to check that
-       * the user has sufficient permission to run this script.
-       *)
-       let permitted =
-        if not anonymous && user = Anonymous then false
-        else
-          match restrict with
-              [] -> true               (* empty list = no restrictions *)
-            | rs ->
-                List.fold_left (||) false
-                  (List.map (fun r -> test_permission host r user) rs) in
+              let rows =
+                PGSQL(dbh)
+                  "select u.id, u.name, u.can_edit, u.can_manage_users,
+                           u.can_manage_contacts, u.can_manage_site,
+                           u.can_edit_global_css, u.can_import_mail,
+                           u.email, u.email_notify
+                      from usercookies uc, users u
+                     where uc.cookie = $cookie
+                       and uc.userid = u.id
+                       and u.hostid = $hostid" in
+              match rows with
+              | [userid, name, can_edit, can_manage_users,
+                 can_manage_contacts, can_manage_site,
+                 can_edit_global_css, can_import_mail,
+                 email, email_notify] ->
+                  (* Every logged in user can view. *)
+                  let perms = [CanView] in
+                  let perms =
+                    if can_edit then CanEdit :: perms
+                    else perms in
+                  let perms =
+                    if can_manage_users then CanManageUsers :: perms
+                    else perms in
+                  let perms =
+                    if can_manage_contacts then CanManageContacts :: perms
+                    else perms in
+                  let perms =
+                    if can_manage_site then CanManageSite :: perms
+                    else perms in
+                  let perms =
+                    if can_edit_global_css then CanEditGlobalCSS :: perms
+                    else perms in
+                  let perms =
+                    if can_import_mail then CanImportMail :: perms
+                    else perms in
+                  (* Preferences. *)
+                  let prefs = { email = email;
+                                email_notify = email_notify; } in
+                  User (userid, name, perms, prefs)
+              | [] -> raise Not_found
+              | _ -> assert false
+            with
+              Not_found -> Anonymous in
 
-       if permitted then (
-        (* Call the actual CGI script. *)
-        run r q dbh hostid host user
-       ) else (
-        if user = Anonymous then (
-          (* Not logged in and no permission to do the requested action,
-           * so redirect to the login script.  If possible set the
-           * redirect parameter so that we return to the right URL.
+          (* If the ~restrict parameter is given, then we want to check that
+           * the user has sufficient permission to run this script.
            *)
-          let redirect =
-            try
-              (* If we passed through mod_rewrite, then it saved the
-               * unmodified original URL in a subprocess environment
-               * variable called SCRIPT_URL:
+          let permitted =
+            if not anonymous && user = Anonymous then false
+            else
+              match restrict with
+              | [] -> true             (* empty list = no restrictions *)
+              | rs ->
+                  List.fold_left (||) false
+                    (List.map (fun r -> test_permission host r user) rs) in
+
+          if permitted then (
+            (* Call the actual CGI script. *)
+            run r q dbh hostid host user
+          ) else (
+            if user = Anonymous then (
+              (* Not logged in and no permission to do the requested action,
+               * so redirect to the login script.  If possible set the
+               * redirect parameter so that we return to the right URL.
                *)
-              let tbl = Request.subprocess_env r in
-              Some (Table.get tbl "SCRIPT_URL")
-            with
-              Not_found ->
+              let redirect =
                 try
-                  (* Otherwise try the ordinary uri field in request_rec. *)
-                  Some (Request.uri r)
-                with Not_found ->
-                  None in
+                  (* If we passed through mod_rewrite, then it saved the
+                   * unmodified original URL in a subprocess environment
+                   * variable called SCRIPT_URL:
+                   *)
+                  let tbl = Request.subprocess_env r in
+                  Some (Table.get tbl "SCRIPT_URL")
+                with
+                  Not_found ->
+                    try
+                      (* Otherwise try the ordinary uri field
+                       * in request_rec.
+                       *)
+                      Some (Request.uri r)
+                    with Not_found ->
+                      None in
+
+              let url =
+                "http://" ^ hostname ^ "/_login" ^
+                  match redirect with
+                  | None -> ""
+                  | Some url -> "?redirect=" ^ Cgi_escape.escape_url url in
+              q#redirect url
+            ) else
+              error ~back_button:true
+                ~title:"Access denied"
+                dbh hostid q
+                "You do not have permission to access this part of the site."
+          );
+
+          None (* no exception *)
+        with
+          exn -> Some exn in
+
+       (* XXX Connection pooling - see above. *)
+       PGOCaml.close dbh;
 
-          let url =
-            "http://" ^ hostname ^ "/_login" ^
-              match redirect with
-              | None -> ""
-              | Some url -> "?redirect=" ^ Cgi_escape.escape_url url in
-          q#redirect url
-        ) else
-          error ~back_button:true
-            ~title:"Access denied"
-            dbh hostid q
-            "You do not have permission to access this part of the site."
-       )
+       (* May re-raise the caught exception. *)
+       Option.may raise exn
     )
 
 (* Convert a section name into something valid for use in <a name="...">
@@ -278,7 +281,7 @@ let linkname_of_sectionname str =
   str
 
 (* List of extensions currently registered. *)
-type extension_t = Dbi.connection -> int -> string -> string
+type extension_t = PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> string
 let extensions = ref ([] : (string * extension_t) list)
 
 (* Maximum degree of redirection. *)
index b72b543..3d00e52 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_create_host.ml,v 1.2 2005/11/17 10:14:43 rich Exp $
+ * $Id: cocanwiki_create_host.ml,v 1.3 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,126 +26,112 @@ open Printf
 
 let create_host dbh canonical_hostname hostnames template
     title username password force_password_change email =
-  let sth =
-    dbh#prepare_cached "set constraints hosts_hostname_cn deferred" in
-  sth#execute [];
-  let sth = dbh#prepare_cached "insert into hosts (canonical_hostname)
-                                  values (?)" in
-  sth#execute [`String canonical_hostname];
+  PGSQL(dbh) "set constraints hosts_hostname_cn deferred";
+  PGSQL(dbh)
+    "insert into hosts (canonical_hostname) values ($canonical_hostname)";
 
-  let hostid = Int64.to_int (sth#serial "hosts_id_seq") in
+  let hostid = PGOCaml.serial4 dbh "hosts_id_seq" in
 
-  let sth = dbh#prepare_cached "insert into hostnames (hostid, name)
-                                  values (?, ?)" in
-  sth#execute [`Int hostid; `String canonical_hostname];
-  List.iter (fun name ->
-              sth#execute [`Int hostid; `String name]) hostnames;
+  let insert name =
+    PGSQL(dbh) "insert into hostnames (hostid, name) values ($hostid, $name)"
+  in
+  insert canonical_hostname;
+  List.iter insert hostnames;
 
   (* Are we creating a blank site or copying a template? *)
-  if template = 0 then (
+  if template = 0l then (
     (* Blank site. *)
-    let sth = dbh#prepare_cached "insert into pages (hostid, url, title,
-                                  description) values (?, 'index', ?, ?)" in
-    sth#execute [`Int hostid; `String title; `String title];
-
+    PGSQL(dbh) "insert into pages (hostid, url, title,
+                  description) values ($hostid, 'index', $title, $title)"
   ) else (
     (* Copy from template. *)
 
-    (*dbh#set_debug true;*)
-
-    let sth = dbh#prepare_cached "select * from hosts where id = ?" in
-    sth#execute [`Int template];
-
-    let names = sth#names in
-    let row = sth#fetch1 () in
-    sth#finish ();
-
-    List.iter
-      (fun (name, field) ->
-        if name <> "id" && name <> "canonical_hostname" &&
-          name <> "is_template" then (
-            let sql = "update hosts set " ^ name ^ " = ? where id = ?" in
-            let sth = dbh#prepare_cached sql in
-            sth#execute [field; `Int hostid]
-          )
-      ) (List.combine names row);
+    (* Use low-level PG'OCaml calls to make a duplicate of the
+     * old hosts row where id = template.
+     *
+     * But don't duplicate id (it's the new site number), or
+     * canonical_hostname (the hostname has changed) or
+     * is_template (new site is a copy of a template, not a template).
+     *)
+    let query = "select * from hosts where id = $1" in
+    PGOCaml.prepare dbh ~query ();
+    let types = Option.get (snd (PGOCaml.describe_statement dbh ())) in
+    let params = [Some (Int32.to_string template)] in
+    let fields = List.hd (PGOCaml.execute dbh ~params ()) in
+
+    List.iter (
+      fun (field, {PGOCaml.name = name}) ->
+       if name <> "id" && name <> "canonical_hostname" &&
+         name <> "is_template" then (
+           let query =
+             sprintf "update hosts set %s = $1 where id = $2" name in
+           PGOCaml.prepare dbh ~query ();
+           let params = [ field; Some (Int32.to_string hostid) ] in
+           ignore (PGOCaml.execute dbh ~params ())
+         )
+    ) (List.combine fields types);
 
     (* Copy pages. *)
-    let sth =
-      dbh#prepare_cached
-       "insert into pages (hostid, url, title, description, redirect, css)
-         select ?, url, title, description, redirect, css
-           from pages
-          where hostid = ? and url is not null" in
-    sth#execute [`Int hostid; `Int template];
+    PGSQL(dbh)
+      "insert into pages (hostid, url, title, description, redirect, css)
+       select $hostid, url, title, description, redirect, css
+         from pages
+        where hostid = $template and url is not null";
 
     (* Copy page contents. *)
-    let sth =
-      dbh#prepare_cached
-       "insert into contents (pageid, ordering, sectionname, content,
-                               divname)
-         select (select id from pages where hostid = ? and url = p.url),
-                c.ordering, c.sectionname, c.content, c.divname
-           from contents c, pages p
-          where c.pageid = p.id and p.hostid = ? and p.url is not null" in
-    sth#execute [`Int hostid; `Int template];
+    PGSQL(dbh)
+      "insert into contents (pageid, ordering, sectionname, content,
+                             divname)
+       select (select id from pages where hostid = $hostid and url = p.url),
+              c.ordering, c.sectionname, c.content, c.divname
+         from contents c, pages p
+        where c.pageid = p.id and p.hostid = $template and p.url is not null";
 
     (* Copy files and images. *)
-    let sth =
-      dbh#prepare_cached
-       "insert into files (hostid, name, content, title, mime_type)
-         select ?, name, content, title, mime_type
-           from files
-          where hostid = ? and name is not null" in
-    sth#execute [`Int hostid; `Int template];
-
-    let sth =
-      dbh#prepare_cached
-       "insert into images (hostid, name, image, width, height, alt, title,
-                             longdesc, class, mime_type, thumbnail,
-                             tn_width, tn_height, tn_mime_type)
-         select ?, name, image, width, height, alt, title, longdesc, class,
-                mime_type, thumbnail, tn_width, tn_height, tn_mime_type
-           from images
-          where hostid = ? and name is not null" in
-    sth#execute [`Int hostid; `Int template];
+    PGSQL(dbh)
+      "insert into files (hostid, name, content, title, mime_type)
+       select $hostid, name, content, title, mime_type
+         from files
+        where hostid = $template and name is not null";
+
+    PGSQL(dbh)
+      "insert into images (hostid, name, image, width, height, alt, title,
+                           longdesc, class, mime_type, thumbnail,
+                           tn_width, tn_height, tn_mime_type)
+       select $hostid, name, image, width, height, alt, title, longdesc, class,
+              mime_type, thumbnail, tn_width, tn_height, tn_mime_type
+         from images
+        where hostid = $template and name is not null";
 
     (* Copy sitemenu. *)
-    let sth =
-      dbh#prepare_cached
-       "insert into sitemenu (hostid, url, label, ordering)
-         select ?, url, label, ordering from sitemenu where hostid = ?" in
-    sth#execute [`Int hostid; `Int template];
+    PGSQL(dbh)
+      "insert into sitemenu (hostid, url, label, ordering)
+       select $hostid, url, label, ordering from sitemenu
+        where hostid = $template";
 
     (* Copy contacts. *)
-    let sth =
-      dbh#prepare_cached
-       "insert into contacts (hostid, name, subject)
-         select ?, name, subject from contacts where hostid = ?" in
-    sth#execute [`Int hostid; `Int template];
-
-    let sth =
-      dbh#prepare_cached
-       "insert into contact_emails (contactid, email)
-         select (select id from contacts
-                  where hostid = ? and name = c.name), ce.email
+    PGSQL(dbh)
+      "insert into contacts (hostid, name, subject)
+       select $hostid, name, subject from contacts where hostid = $template";
+
+    PGSQL(dbh)
+      "insert into contact_emails (contactid, email)
+       select (select id from contacts
+               where hostid = $hostid and name = c.name), ce.email
            from contact_emails ce, contacts c
-          where ce.contactid = c.id and c.hostid = ?" in
-    sth#execute [`Int hostid; `Int template];
+          where ce.contactid = c.id and c.hostid = $template";
 
     (* Set the title of the index page. *)
-    let sth = dbh#prepare_cached "update pages set title = ?
-                                   where hostid = ? and url = 'index'" in
-    sth#execute [`String title; `Int hostid]
+    PGSQL(dbh)
+      "update pages set title = $title
+        where hostid = $hostid and url = 'index'"
   );
 
   (* Create the administrator user. *)
-  let email = match email with Some e -> `String e | None -> `Null in
-
-  let sth = dbh#prepare_cached "insert into users (hostid, name, password,
-                                force_password_change, email, can_manage_users)
-                                values (?, ?, ?, ?, ?, true)" in
-  sth#execute [`Int hostid; `String username; `String password;
-              `Bool force_password_change; email];
+  PGSQL(dbh)
+    "insert into users (hostid, name, password,
+                        force_password_change, email, can_manage_users)
+     values ($hostid, $username, $password, $force_password_change,
+             $?email, true)";
 
   hostid
index f4ed7f7..60240be 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_create_host.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_create_host.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,5 +19,4 @@
  * Boston, MA 02111-1307, USA.
  *)
 
-val create_host : Dbi.connection -> string -> string list -> int ->
-  string -> string -> string -> bool -> string option -> int
+val create_host : PGOCaml.pa_pg_data PGOCaml.t -> string -> string list -> int32 -> string -> string -> string -> bool -> string option -> int32
index 124f3f7..245b3d0 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_date.ml,v 1.3 2005/11/23 11:32:38 rich Exp $
+ * $Id: cocanwiki_date.ml,v 1.4 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,38 +24,12 @@ open Registry
 open Cgi
 open Printf
 
-let short_weekday = function
-  | Date.Sun -> "Sun" | Date.Mon -> "Mon" | Date.Tue -> "Tue"
-  | Date.Wed -> "Wed" | Date.Thu -> "Thu" | Date.Fri -> "Fri"
-  | Date.Sat -> "Sat"
-
-let short_month = function
-  | 1 -> "Jan" | 2 -> "Feb" | 3 -> "Mar" | 4 -> "Apr"
-  | 5 -> "May" | 6 -> "Jun" | 7 -> "Jul" | 8 -> "Aug"
-  | 9 -> "Sep" | 10 -> "Oct" | 11 -> "Nov" | 12 -> "Dec"
-  | _ -> invalid_arg "short_month"
-
-let long_month = function
-  | 1 -> "January" | 2 -> "February" | 3 -> "March" | 4 -> "April"
-  | 5 -> "May" | 6 -> "June" | 7 -> "July" | 8 -> "August"
-  | 9 -> "September" | 10 -> "October" | 11 -> "November" | 12 -> "December"
-  | _ -> invalid_arg "short_month"
-
 (* Generate a printable datestamp for pages. *)
-let printable_date' date =
-  sprintf "%d %s %04d" date.Dbi.day (short_month date.Dbi.month) date.Dbi.year
+let printable_date' = Printer.DatePrinter.sprint "%d %b %Y"
 
-let printable_date (date, _) = printable_date' date
+let printable_date = Printer.CalendarPrinter.sprint "%d %b %Y"
 
-let printable_date_time (date, time) =
-  sprintf "%d %s %04d %02d:%02d" date.Dbi.day (short_month date.Dbi.month)
-    date.Dbi.year time.Dbi.hour time.Dbi.min
+let printable_date_time = Printer.CalendarPrinter.sprint "%d %b %Y %H:%M"
 
 (* ISO 8601 timestamp. *)
-let iso_8601_date_time (date, time) =
-  sprintf "%04d-%02d-%02dT%02d:%02d:%02d"
-    date.Dbi.year date.Dbi.month date.Dbi.day
-    time.Dbi.hour time.Dbi.min time.Dbi.sec ^
-  match time.Dbi.timezone with
-  | None -> "Z"
-  | Some t -> sprintf "+%02d:00" t
+let iso_8601_date_time = Printer.CalendarPrinter.sprint "%iT%TZ"
index 9238686..004960d 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_diff.ml,v 1.3 2004/11/01 12:57:53 rich Exp $
+ * $Id: cocanwiki_diff.ml,v 1.4 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -79,42 +79,49 @@ let diff_cmd old_page new_page =
 
   String.concat "\n" diff
 
-let get_version_for_diff (dbh : Dbi.connection) version =
-  if version = 0 then "" else (
-    let sth = dbh#prepare_cached "select coalesce (css, '') as css
-                                    from pages where id = ?" in
-    sth#execute [`Int version];
+let get_version_for_diff dbh version =
+  if version = 0l then ""
+  else (
+    let css = List.hd (
+      PGSQL(dbh)
+       "select css from pages where id = $version"
+    ) in
+    let css = match css with None -> "" | Some css -> css in
 
-    let css = sth#fetch1string () in
-
-    let sth = dbh#prepare_cached "select coalesce (sectionname, ''), content
-                                    from contents where pageid = ?
-                                   order by ordering" in
-    sth#execute [`Int version];
+    let rows = PGSQL(dbh)
+      "select sectionname, content
+         from contents where pageid = $version
+        order by ordering" in
 
     let sections =
-      sth#map (function
-                  [`String sectionname; `String content] ->
-                    sectionname, content
-                | _ -> assert false) in
+      List.map (
+       function
+       | (Some sectionname, content) ->
+           sectionname, content
+       | (None, content) ->
+           "", content
+      ) rows in
     let page = page_for_diff css sections in
 
     page
   )
 
-let get_diff (dbh : Dbi.connection) hostid page ?old_version ~version ()=
+let get_diff dbh hostid page ?old_version ~version ()=
   let old_version =
     match old_version with
       | Some version -> version
       | None ->
-         let sth = dbh#prepare_cached "select id from pages
-                                         where hostid = ?
-                                           and url_deleted = ? and id < ?
-                                         order by 1 desc limit 1" in
-         sth#execute [`Int hostid; `String page; `Int version];
-
-         try sth#fetch1int ()
-         with Not_found -> 0 in
+         try
+           List.hd (
+             PGSQL(dbh)
+               "select id from pages
+                  where hostid = $hostid
+                    and url_deleted = $page
+                    and id < $version
+                  order by 1 desc limit 1"
+           )
+         with
+           Not_found | ExtList.List.Empty_list -> 0l in
 
   (* Get the two versions. *)
   let new_page = get_version_for_diff dbh version in
index 6bbeb71..3f278dd 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_diff.mli,v 1.2 2004/11/01 12:57:53 rich Exp $
+ * $Id: cocanwiki_diff.mli,v 1.3 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@ val page_for_diff : string -> (string * string) list -> string
 
 val diff_cmd : string -> string -> string
 
-val get_version_for_diff : Dbi.connection -> int -> string
+val get_version_for_diff : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string
 
-val get_diff : Dbi.connection -> int ->
-  string -> ?old_version:int -> version:int -> unit -> string * int
+val get_diff : PGOCaml.pa_pg_data PGOCaml.t -> int32 ->
+  string -> ?old_version:int32 -> version:int32 -> unit -> string * int32
index 59f3b04..c63b846 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_emailnotify.ml,v 1.6 2005/03/31 14:24:04 rich Exp $
+ * $Id: cocanwiki_emailnotify.ml,v 1.7 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,12 +24,14 @@ open Registry
 open Cgi
 open Printf
 
+open ExtList
+
 open Cocanwiki
 
 (* This is where we coordinate email notification from various
  * scripts which create or update the wiki.
  *)
-let email_notify ~subject ~body ?user (dbh : Dbi.connection) hostid =
+let email_notify ~subject ~body ?user dbh hostid =
   (* Get own userid, if we have it.  Don't want to send email
    * notification back to the person who changed the page.  If
    * we don't have a userid, set it to 0, because no real user can
@@ -40,7 +42,7 @@ let email_notify ~subject ~body ?user (dbh : Dbi.connection) hostid =
   let own_userid, from =
     match user with
       | None
-      | Some Anonymous -> 0, None
+      | Some Anonymous -> 0l, None
       | Some (User (userid, _, _, prefs)) -> userid, prefs.email in
 
   (* Send a change email to everyone who hasn't opted out using
@@ -48,17 +50,17 @@ let email_notify ~subject ~body ?user (dbh : Dbi.connection) hostid =
    * 'email_notify' table.  Don't send email to invited accounts
    * who have not yet confirmed.
    *)
-  let sth = dbh#prepare_cached "select email, name
-                                  from users
-                                 where hostid = ? and id <> ? and email_notify
-                                   and email is not null
-                                   and invite is null" in
-  sth#execute [`Int hostid; `Int own_userid];
-
-  let to_addr = sth#map (function
-                          | [`String email; `String name] ->
-                              "\"" ^ name ^ "\" <" ^ email ^ ">"
-                          | _ -> assert false) in
+  let rows = PGSQL(dbh)
+    "select name, email
+       from users
+      where hostid = $hostid and id <> $own_userid and email_notify
+        and email is not null and invite is null" in
+  let to_addr = List.filter_map (
+    function
+    | (name, Some email) ->
+       Some ("\"" ^ name ^ "\" <" ^ email ^ ">")
+    | (name, None) -> None
+  ) rows in
 
   if to_addr <> [] then (
     (* Prepare the body of the message.  The assumption is that
index 2b3951f..1d54ca7 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_ext_calendar.ml,v 1.2 2005/04/02 17:30:54 rich Exp $
+ * $Id: cocanwiki_ext_calendar.ml,v 1.3 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ let rec range a b =
   else
     []
 
-let extension (dbh : Dbi.connection) hostid url =
+let extension dbh hostid url =
   (* Validate a date in the form "yyyy[/mm[/dd]]".  Returns a (yyyy, mm, dd)
    * tuple with missing fields set to 0.  If the string doesn't parse or the
    * date isn't valid, then raises Not_found.
@@ -93,19 +93,18 @@ let extension (dbh : Dbi.connection) hostid url =
   (* From the links table, find all links to this page, or sub-calendar pages.
    * This query overselects.  We then filter the real pages in OCaml.
    *)
-  let sth =
-    dbh#prepare_cached
+  let rows =
+    let patt = url ^ "%" in
+    PGSQL(dbh)
       "select li.from_url, p.title, li.to_url
          from links li, pages p
-        where li.hostid = ? and li.to_url like ?
+        where li.hostid = $hostid and li.to_url like $patt
           and li.hostid = p.hostid and li.from_url = p.url" in
-  sth#execute [`Int hostid; `String (url ^ "%")];
 
   let pages =
     let results =
-      sth#map (function [`String from_url; `String title; `String to_url] ->
-                from_url, title, to_url
-                | _ -> assert false) in
+      List.map (fun (from_url, title, to_url) ->
+                 from_url, title, to_url) rows in
     List.filter_map
       (fun (from_url, title, to_url) ->
         try let date = valid_date to_url in Some (date, (title, from_url))
@@ -144,7 +143,8 @@ let extension (dbh : Dbi.connection) hostid url =
            let template = year_1m_template in
            template#set "yyyy" (string_of_int yyyy);
            template#set "mm" (sprintf "%02d" mm);
-           template#set "month_name" (long_month mm);
+           template#set "month_name"
+             (!Printer.month_name (Date.month_of_int mm));
            let dow = Date.day_of_week (Date.make yyyy mm 1) in
            let max_dd = Date.days_in_month (Date.make yyyy mm 1) in
            let dd = ref (1 - int_of_day_of_week dow) in
@@ -196,7 +196,7 @@ let extension (dbh : Dbi.connection) hostid url =
     | Some (yyyy, mm, 0) ->            (* Month view. *)
        let template = month_template in
 
-       template#set "month_name" (long_month mm);
+       template#set "month_name" (!Printer.month_name (Date.month_of_int mm));
        template#set "yyyy" (string_of_int yyyy);
        template#set "mm" (sprintf "%02d" mm);
 
@@ -258,11 +258,11 @@ let extension (dbh : Dbi.connection) hostid url =
        template#set "mm" (sprintf "%02d" mm);
        template#set "dd" (sprintf "%02d" dd);
 
-       template#set "month_name" (long_month mm);
+       template#set "month_name" (!Printer.month_name (Date.month_of_int mm));
 
        let t = Date.make yyyy mm dd in
        let dow = Date.day_of_week t in
-       template#set "short_weekday" (short_weekday dow);
+       template#set "short_weekday" (Printer.short_name_of_day dow);
 
        let oneday = Date.Period.day 1 in
        let prev_t = Date.rem t oneday in
index 89d6621..2589050 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_links.ml,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_links.ml,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -89,41 +89,37 @@ let get_links_from_section dbh hostid content =
 
 let insert_link dbh hostid from_url to_url =
   if from_url <> to_url then (
-    let sth = dbh#prepare_cached "select 1 from links
-                                   where hostid = ?
-                                     and from_url = ? and to_url = ?" in
-    sth#execute [`Int hostid; `String from_url; `String to_url];
-
-    let exists = try sth#fetch1int () = 1 with Not_found -> false in
+    let exists =
+      [] <> PGSQL(dbh) "select 1 from links
+                         where hostid = $hostid
+                           and from_url = $from_url
+                           and to_url = $to_url" in
 
     if not exists then (
-      let sth =
-       dbh#prepare_cached "insert into links (hostid, from_url, to_url)
-                            values (?, ?, ?)" in
-      sth#execute [`Int hostid; `String from_url; `String to_url]
+      PGSQL(dbh) "insert into links (hostid, from_url, to_url)
+                            values ($hostid, $from_url, $to_url)"
     )
   )
 
 let update_links_for_page dbh hostid page =
   (* Delete entries in the old links table. *)
-  let sth = dbh#prepare_cached "delete from links
-                                 where hostid = ? and from_url = ?" in
-  sth#execute [`Int hostid; `String page];
+  PGSQL(dbh) "delete from links
+               where hostid = $hostid and from_url = $page";
 
   (* Get the sections from the page. *)
-  let sth = dbh#prepare_cached "select c.content from contents c, pages p
-                                 where c.pageid = p.id
-                                   and p.hostid = ?
-                                   and p.url = ?
-                                   and p.redirect is null" in
-  sth#execute [`Int hostid; `String page];
+  let rows = PGSQL(dbh)
+    "select c.content from contents c, pages p
+      where c.pageid = p.id
+        and p.hostid = $hostid
+        and p.url = $page
+        and p.redirect is null" in
 
   (* Get the links from each section. *)
-  sth#iter
-    (function [`String content] ->
-       let links = get_links_from_section dbh hostid content in
-       List.iter (insert_link dbh hostid page) links
-       | _ -> assert false)
+  List.iter (
+    fun content ->
+      let links = get_links_from_section dbh hostid content in
+      List.iter (insert_link dbh hostid page) links
+  ) rows
 
 (* Because of redirects, getting the list of pages which link to this
  * page isn't a matter of just doing 'select from_url from links ...'.
@@ -134,7 +130,7 @@ let update_links_for_page dbh hostid page =
  * to page C, then querying what links to page C will list page A twice.
  * This is a bug.
  *)
-let what_links_here (dbh : Dbi.connection) hostid page =
+let what_links_here dbh hostid page =
   (* Build up the complete list of URLs which redirect to the target
    * page, within max_redirect redirections.  This is sort of like
    * Prim's algorithm.
@@ -143,16 +139,15 @@ let what_links_here (dbh : Dbi.connection) hostid page =
   let found = ref true in
   let i = ref 1 in
   while !found && !i <= max_redirect do
-    let qs = Dbi.placeholders (List.length !urls) in
-    let sql =
+    let new_urls =
+      let urls = !urls in
+      PGSQL(dbh)
       "select url from pages
-        where hostid = ?
+        where hostid = $hostid
           and url is not null and redirect is not null
-          and url not in " ^ qs ^ " and redirect in " ^ qs in
-    let sth = dbh#prepare_cached sql in
-    let args = List.map (fun s -> `String s) !urls in
-    sth#execute (`Int hostid :: (args @ args));
-    let new_urls = sth#map (function [`String s] -> s | _ -> assert false) in
+          and url not in $@urls and redirect in $@urls" in
+    let new_urls =
+      List.map (function | Some url -> url | None -> assert false) new_urls in
     urls := !urls @ new_urls;
     found := new_urls <> [];
     incr i
@@ -163,16 +158,12 @@ let what_links_here (dbh : Dbi.connection) hostid page =
   (* Now find any pages which link to one of these target pages.  For
    * convenience we also select out the titles.
    *)
-  let qs = Dbi.placeholders (List.length urls) in
-  let sth =
-    dbh#prepare_cached
-      ("select li.from_url, p.title, li.from_url = 'index'
-          from links li, pages p
-         where li.hostid = ? and li.to_url in " ^ qs ^ "
-           and li.hostid = p.hostid and li.from_url = p.url
-         order by 3 desc, 2, 1") in
-  sth#execute (`Int hostid :: (List.map (fun s -> `String s) urls));
-
-  sth#map (function
-            | [`String url; `String title; _] -> url, title
-            | _ -> assert false)
+  let rows =
+    PGSQL(dbh)
+      "select li.from_url, p.title, li.from_url = 'index'
+         from links li, pages p
+        where li.hostid = $hostid and li.to_url in $@urls
+          and li.hostid = p.hostid and li.from_url = p.url
+        order by 3 desc, 2, 1" in
+
+  List.map (fun (url, title, _) -> url, title) rows
index 59d0c0c..09ea363 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_links.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_links.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,8 +19,7 @@
  * Boston, MA 02111-1307, USA.
  *)
 
-val get_links_from_section : Dbi.connection -> int -> string -> string list
-val update_links_for_page : Dbi.connection -> int -> string -> unit
-val insert_link : Dbi.connection -> int -> string -> string -> unit
-
-val what_links_here : Dbi.connection -> int -> string -> (string * string) list
+val get_links_from_section : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> string list
+val update_links_for_page : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> unit
+val insert_link : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> string -> unit
+val what_links_here : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> (string * string) list
index 6ac57f2..494e60c 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_mail.ml,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_mail.ml,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -148,13 +148,13 @@ struct
 end
 
 type message =
-    { id : int;
+    { id : int32;
       inet_message_id : string;
       references : string list;
       subject : string;
       base_subject : string;
       is_reply : bool;
-      message_date : Dbi.datetime }
+      message_date : PGOCaml.timestamptz }
 
 type tree = Tree of message option * tree list
 
@@ -162,35 +162,37 @@ type tree = Tree of message option * tree list
  * The algorithm was originally by JWZ, http://www.jwz.org/doc/threading.html,
  * simplified and implemented by Radu Grigore <radugrigore@yahoo.com>.
  *)
-let thread_mail (dbh : Dbi.connection) hostid ?user ?r year month =
+let thread_mail dbh hostid ?user ?r year month =
   (* Pull out all the emails relevant to this month. *)
-  let sth =
-    dbh#prepare_cached "select id, subject, inet_message_id, message_date
-                          from messages
-                         where hostid = ?
-                           and extract (year from message_date) = ?
-                           and extract (month from message_date) = ?" in
-  sth#execute [`Int hostid; `Int year; `Int month];
+  let rows =
+    let year = Int32.of_int year in
+    let month = Int32.of_int month in
+    PGSQL(dbh)
+      "select id, subject, inet_message_id, message_date
+         from messages
+        where hostid = $hostid
+          and extract (year from message_date) :: int = $year
+          and extract (month from message_date) :: int = $month" in
 
   let msgs =
-    sth#map
-      (function [`Int id; `String subject; `String inet_message_id;
-                `Timestamp message_date] ->
-        id, (inet_message_id, subject, message_date)
-        | _ -> assert false) in
+    List.map (
+      fun (id, subject, inet_message_id, message_date) ->
+       id, (inet_message_id, subject, message_date)
+    ) rows in
 
   let references =
     if msgs <> [] then (
-      let sth =
-       let qs = Dbi.placeholders (List.length msgs) in
-       dbh#prepare_cached ("select message_id, inet_message_id, ordering
-                               from msg_references
-                              where message_id in " ^ qs ^ "
-                              order by message_id, ordering") in
-      sth#execute (List.map (fun (id, _) -> `Int id) msgs);
-      sth#map (function [`Int id; `String inet_message_id; _] ->
-                id, inet_message_id
-                | _ -> assert false)
+      let ids = List.map fst msgs in
+      let rows =
+       PGSQL(dbh)
+         "select message_id, inet_message_id, ordering
+             from msg_references
+            where message_id in $@ids
+            order by message_id, ordering" in
+      List.map (
+       fun (id, inet_message_id, _) ->
+         id, inet_message_id
+      ) rows
     ) else [] in
 
   (* Aggregate the msgs and references structures together.
@@ -354,11 +356,13 @@ let thread_mail (dbh : Dbi.connection) hostid ?user ?r year month =
 
   let first_section =
     let sectionname =
-      sprintf "Thread index for %s %04d" (long_month month) year in
+      sprintf "Thread index for %s %04d"
+       (!Printer.month_name (Date.month_of_int month)) year in
     let content =
       template#set "year" (string_of_int year);
       template#set "month" (sprintf "%02d" month);
-      template#set "long_month" (long_month month);
+      template#set "long_month"
+       (!Printer.month_name (Date.month_of_int month));
       let prev_year, prev_month =
        if month = 1 then year - 1, 12
        else year, month - 1 in
@@ -379,7 +383,7 @@ let thread_mail (dbh : Dbi.connection) hostid ?user ?r year month =
              let {id = id; subject = subject} = message in
 
              let url =
-               let title = sprintf "Mail/%s (%d)" subject id in
+               let title = sprintf "Mail/%s (%ld)" subject id in
                match Wikilib.generate_url_of_title dbh hostid title with
                    Wikilib.GenURL_OK url | Wikilib.GenURL_Duplicate url -> url
                  | Wikilib.GenURL_TooShort | Wikilib.GenURL_BadURL ->
@@ -398,15 +402,15 @@ let thread_mail (dbh : Dbi.connection) hostid ?user ?r year month =
 
       template#to_string
     in
-    (sectionname, "", content)
+    (Some sectionname, None, content)
   in
 
   let contents =
-    match model.contents with
+    match model.contents_ with
       | [] | [_] -> [ first_section ]
       | x :: xs -> first_section :: xs in
 
-  let model = { model with contents = contents } in
+  let model = { model with contents_ = contents } in
 
   (* Save the page. *)
   try
index 93c7b00..f651106 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_mail.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_mail.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 open Cocanwiki
 
-val thread_mail : Dbi.connection -> int -> ?user:user_t -> ?r:Apache.Request.t -> int -> int -> unit
+val thread_mail : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> ?user:user_t -> ?r:Apache.Request.t -> int -> int -> unit
   (** [thread_mail dbh hostid year month] rebuilds the thread index
     * for (year, month).
     *)
index f713277..948f8a5 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_pages.ml,v 1.4 2005/11/17 10:14:43 rich Exp $
+ * $Id: cocanwiki_pages.ml,v 1.5 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,17 +27,20 @@ open Cocanwiki_strings
 type pt = Page of string | Title of string
 
 type model = {
-  id : int;                            (* Original page ID (0 = none). *)
+  id : int32;                          (* Original page ID (0 = none). *)
   pt : pt;                             (* Page of title (only used if id=0) *)
   description : string;                        (* Description. *)
-  redirect : string;                   (* Redirect to ("" = none). *)
-  contents : (string * string * string) list;
+  redirect : string option;            (* Redirect to. *)
+  (* NB. Don't call this 'contents' because that clashes with the
+   * Pervasives.contents fields of the ref type.
+   *)
+  contents_ : (string option * string option * string) list;
                                        (* (sectionname, divname, content)
                                         * for each section. *)
 }
 
 exception SaveURLError
-exception SaveConflict of int * int * string * string
+exception SaveConflict of int32 * int32 * string * string
 
 let new_page pt =
   let description =
@@ -45,98 +48,78 @@ let new_page pt =
        Page page -> page
       | Title title -> title in
 
-  let model = { id = 0;
+  let model = { id = 0l;
                pt = pt;
                description = description;
-               redirect = "";
-               contents = [] } in
+               redirect = None;
+               contents_ = [] } in
   model
 
 let new_page_with_title title =
   (* Initial page contents. *)
-  let contents = [ "", "", "<b>" ^ title ^ "</b> is " ] in
-  let model = { id = 0;
+  let contents = [ None, None, "<b>" ^ title ^ "</b> is " ] in
+  let model = { id = 0l;
                pt = Title title;
                description = title;
-               redirect = "";
-               contents = contents } in
+               redirect = None;
+               contents_ = contents } in
   model
 
-let load_page (dbh : Dbi.connection) hostid ~url ?version () =
+let load_page dbh hostid ~url ?version () =
   (* Pull out the page itself from the database. *)
-  let sth =
+  let rows =
     match version with
-       None ->
-         let sth = dbh#prepare_cached "select id, title, description,
-                                               coalesce (redirect, '')
-                                          from pages
-                                         where hostid = ? and url = ?" in
-         sth#execute [`Int hostid; `String url];
-         sth
-      | Some version ->
-         let sth = dbh#prepare_cached "select id, title, description,
-                                               coalesce (redirect, '')
-                                          from pages
-                                         where hostid = ? and id = ? and
-                                               (url = ? or url_deleted = ?)" in
-         sth#execute [`Int hostid; `String url; `String url];
-         sth in
+    | None ->
+       PGSQL(dbh) "select id, title, description, redirect
+                      from pages
+                     where hostid = $hostid and url = $url"
+    | Some version ->
+       PGSQL(dbh) "select id, title, description, redirect
+                      from pages
+                     where hostid = $hostid and id = $version and
+                           (url = $url or url_deleted = $url)" in
 
   let pageid, title, description, redirect =
-    match sth#fetch1 () with
-       [`Int pageid; `String title; `String description; `String redirect] ->
-         pageid, title, description, redirect
-      | _ -> assert false in
+    match rows with
+    | [row] -> row
+    | _ -> raise Not_found in
 
   (* Get the sections. *)
-  let sth = dbh#prepare_cached "select coalesce (sectionname, ''),
-                                       content,
-                                       coalesce (divname, '')
-                                  from contents
-                                 where pageid = ?
-                                 order by ordering" in
-  sth#execute [`Int pageid];
-
-  let contents =
-    sth#map (function
-              | [`String sectionname; `String content; `String divname] ->
-                  sectionname, divname, content
-              | _ -> assert false) in
+  let contents = PGSQL(dbh)
+    "select sectionname, divname, content
+       from contents
+      where pageid = $pageid
+      order by ordering" in
 
   let model = { id = pageid;
                pt = Page url;
                description = description;
                redirect = redirect;
-               contents = contents; } in
+               contents_ = contents } in
   model
 
-let save_page (dbh : Dbi.connection) hostid ?user ?r model =
+let save_page dbh hostid ?user ?r model =
   (* Logging information, if available. *)
   let logged_user =
     match user with
-       None -> `Null
+       None -> None
       | Some user ->
          match user with
-           | User (id, _, _, _) -> `Int id
-           | _ -> `Null in
+           | User (id, _, _, _) -> Some id
+           | _ -> None in
 
   let logged_ip =
     match r with
-       None -> `Null
+       None -> None
       | Some r ->
-         try `String (Connection.remote_ip (Request.connection r))
-         with Not_found -> `Null in
-
-  (* Get redirect. *)
-  let redirect =
-    if model.redirect = "" then `Null
-    else `String model.redirect in
+         try Some (Connection.remote_ip (Request.connection r))
+         with Not_found -> None in
 
   let url, pageid =
     (* Creating a new page (id = 0)?  If so, we're just going to insert
      * a new row, which is easy.
      *)
-    if model.id = 0 then (
+    if model.id = 0l then (
       (* Create the page title or URL. *)
       let url, title =
        match model.pt with
@@ -147,83 +130,76 @@ let save_page (dbh : Dbi.connection) hostid ?user ?r model =
                | _ ->
                    raise SaveURLError in
 
-      let sth = dbh#prepare_cached "insert into pages (hostid, url, title,
-                                      description, logged_ip, logged_user,
-                                      redirect)
-                                      values (?, ?, ?, ?, ?, ?, ?)" in
-      sth#execute [`Int hostid; `String url; `String title;
-                  `String model.description; logged_ip; logged_user;
-                  redirect];
+      let description = model.description in
+      let redirect = model.redirect in
+      PGSQL(dbh) "insert into pages (hostid, url, title,
+                                     description, logged_ip, logged_user,
+                                     redirect)
+                  values ($hostid, $url, $title, $description,
+                          $?logged_ip, $?logged_user, $?redirect)";
 
-      let pageid = Int64.to_int (sth#serial "pages_id_seq") in
+      let pageid = PGOCaml.serial4 dbh "pages_id_seq" in
 
       (* Create the page contents. *)
-      let sth = dbh#prepare_cached "insert into contents (pageid,
-                                      ordering, sectionname, divname,
-                                      content)
-                                      values (?, ?, ?, ?, ?)" in
       let ordering = ref 0 in  (* Creating new ordering. *)
-      List.iter (fun (sectionname, divname, content) ->
-                  let divname =
-                    if string_is_whitespace divname then `Null
-                    else `String divname in
-                  let sectionname =
-                    if string_is_whitespace sectionname then `Null
-                    else `String sectionname in
-                  incr ordering; let ordering = !ordering in
-                  sth#execute [`Int pageid; `Int ordering;
-                               sectionname; divname;
-                               `String content])
-       model.contents;
+      List.iter (
+       fun (sectionname, divname, content) ->
+         incr ordering; let ordering = Int32.of_int !ordering in
+         PGSQL(dbh)
+           "insert into contents (pageid, ordering, sectionname, divname,
+                                   content)
+             values ($pageid, $ordering,
+                     $?sectionname, $?divname, $content)"
+      ) model.contents_;
 
       url, pageid
     )
       (* Otherwise it's an old page which we're updating. *)
     else (
       (* Pull out fields from the database. *)
-      let sth = dbh#prepare_cached "select creation_date,
-                                           coalesce (url, url_deleted),
-                                           title, css
-                                      from pages
-                                     where hostid = ? and id = ?" in
-      sth#execute [`Int hostid; `Int model.id];
+      let model_id = model.id in
+      let rows =
+       PGSQL(dbh)
+       "select creation_date, coalesce (url, url_deleted),
+                title, css
+           from pages
+          where hostid = $hostid and id = $model_id" in
 
       let creation_date, url, title, css =
-       match sth#fetch1 () with
-           [ creation_date; `String url; `String title; css ] ->
-             creation_date, url, title, css
-         | _ -> assert false in
+       match rows with
+       | [ row ] -> row
+       | _ -> assert false in
+      let url = Option.get url in
 
       (* Title changed? *)
       let title =
        match model.pt with
-           Title new_title when title <> new_title -> new_title
-         | _ -> title in
+       | Title new_title when title <> new_title -> new_title
+       | _ -> title in
 
       (* Has someone else edited this page in the meantime? *)
-      let sth = dbh#prepare_cached "select max(id) from pages
-                                     where hostid = ? and url = ?" in
-      sth#execute [`Int hostid; `String url];
+      let max_id = Option.get (
+       List.hd (
+         PGSQL(dbh) "select max(id) from pages
+                       where hostid = $hostid and url = $url"
+       )
+      ) in
 
-      let max_id = sth#fetch1int () in
-      let edited = max_id <> model.id in
+      let edited = max_id <> model_id in
 
       if edited then (
-       let css = match css with
-           `Null -> "" | `String css -> css
-         | _ -> assert false in
-       raise (SaveConflict (max_id, model.id, url, css))
+       let css = match css with None -> "" | Some css -> css in
+       raise (SaveConflict (max_id, model_id, url, css))
       );
 
       (* Defer the pages_redirect_cn constraint because that would
        * temporarily fail on the next UPDATE.
        *)
-      let sth =
-       dbh#prepare_cached
-         "set constraints pages_redirect_cn, sitemenu_url_cn,
+      PGSQL(dbh)
+       "set constraints
+               pages_redirect_cn, sitemenu_url_cn,
                page_emails_url_cn, links_from_cn, recently_visited_url_cn
-               deferred" in
-      sth#execute [];
+             deferred";
 
       (* Mark the old page as deleted.  NB. There is a small race
        * condition here because PostgreSQL doesn't do isolation
@@ -231,41 +207,31 @@ let save_page (dbh : Dbi.connection) hostid ?user ?r model =
        * delete and the creation of the new page, then they'll get
        * a page not found error. (XXX)
        *)
-      let sth = dbh#prepare_cached "update pages set url_deleted = url,
-                                                     url = null
-                                     where hostid = ? and id = ?" in
-      sth#execute [`Int hostid; `Int model.id];
-
-      (* Create the new page. *)
-      let sth = dbh#prepare_cached "insert into pages (hostid, url, title,
-                                    description, creation_date, logged_ip,
-                                    logged_user, redirect, css)
-                                    values (?, ?, ?, ?, ?, ?, ?, ?, ?)" in
-      sth#execute [`Int hostid; `String url; `String title;
-                  `String model.description; creation_date; logged_ip;
-                  logged_user; redirect; css];
+      PGSQL(dbh) "update pages set url_deleted = url, url = null
+                   where hostid = $hostid and id = $model_id";
+
+      let description = model.description in
+      let redirect = model.redirect in
+      PGSQL(dbh)
+       "insert into pages (hostid, url, title,
+                            description, creation_date, logged_ip,
+                            logged_user, redirect, css)
+         values ($hostid, $url, $title, $description, $creation_date,
+                 $?logged_ip, $?logged_user, $?redirect, $?css)";
 
       (* New page ID <> old page ID model.id. *)
-      let pageid = Int64.to_int (sth#serial "pages_id_seq") in
+      let pageid = PGOCaml.serial4 dbh "pages_id_seq" in
 
       (* Create the page contents. *)
-      let sth = dbh#prepare_cached "insert into contents (pageid,
-                                    ordering, sectionname, divname,
-                                    content)
-                                    values (?, ?, ?, ?, ?)" in
       let ordering = ref 0 in  (* Creating new ordering. *)
-      List.iter (fun (sectionname, divname, content) ->
-                  let divname =
-                    if string_is_whitespace divname then `Null
-                    else `String divname in
-                  let sectionname =
-                    if string_is_whitespace sectionname then `Null
-                    else `String sectionname in
-                  incr ordering; let ordering = !ordering in
-                  sth#execute [`Int pageid; `Int ordering;
-                               sectionname; divname;
-                               `String content])
-       model.contents;
+      List.iter (
+       fun (sectionname, divname, content) ->
+         incr ordering; let ordering = Int32.of_int !ordering in
+         PGSQL(dbh) "insert into contents (pageid,
+                         ordering, sectionname, divname, content)
+                      values ($pageid, $ordering, $?sectionname,
+                              $?divname, $content)"
+      ) model.contents_;
 
       url, pageid
     ) in
index 92c6809..b7082c9 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_pages.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_pages.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,17 +25,17 @@ open Cocanwiki
 type pt = Page of string | Title of string
 
 type model = {
-  id : int;                            (* Original page ID (0 = none). *)
+  id : int32;                          (* Original page ID (0 = none). *)
   pt : pt;                             (* Page of title (only used if id=0) *)
   description : string;                        (* Description. *)
-  redirect : string;                   (* Redirect to ("" = none). *)
-  contents : (string * string * string) list;
+  redirect : string option;            (* Redirect to. *)
+  contents_ : (string option * string option * string) list;
                                        (* (sectionname, divname, content)
                                         * for each section. *)
 }
 
 exception SaveURLError
-exception SaveConflict of int * int * string * string
+exception SaveConflict of int32 * int32 * string * string
 
 val new_page : pt -> model
   (** Create a new, blank page. *)
@@ -45,7 +45,7 @@ val new_page_with_title : string -> model
     * a title and begins an introductory paragraph for the user.
     *)
 
-val load_page : Dbi.connection -> int -> url:string -> ?version:int -> unit -> model
+val load_page : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> url:string -> ?version:int32 -> unit -> model
   (** Load a page from the database.  A non-current version can be
     * specified with the optional [?version] parameter, otherwise the
     * latest version is loaded.
@@ -53,7 +53,7 @@ val load_page : Dbi.connection -> int -> url:string -> ?version:int -> unit -> m
     * @raise Not_found If the page cannot be found.
     *)
 
-val save_page : Dbi.connection -> int -> ?user:user_t -> ?r:Apache.Request.t -> model -> string * int
+val save_page : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> ?user:user_t -> ?r:Apache.Request.t -> model -> string * int32
   (** Save a page.  If the page is new, this creates a new page in the
     * database.  If the page is old, then the page is edited.
     *
index 40a7ad8..6f8e259 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_server_settings.ml,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_server_settings.ml,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,26 +37,16 @@ open Printf
  *)
 let server_settings_version, server_settings_stats_page,
     server_settings_crash_email =
-  let default = 1, None, None in
+  let default = 1l, None, None in
   let settings = ref None in
-  let get_settings (dbh : Dbi.connection) =
-    let sth = dbh#prepare "select version, stats_page, crash_email
-                             from server_settings" in
-    sth#execute [];
+  let get_settings dbh =
+    let rows = PGSQL(dbh)
+      "select version, stats_page, crash_email from server_settings" in
     let s =
-      try
-       (match sth#fetch1 () with
-          | [ `Int version; (`String _ | `Null) as stats_page;
-              (`String _ | `Null) as crash_email ] ->
-              let stats_page =
-                match stats_page with `String s -> Some s | `Null -> None in
-              let crash_email =
-                match crash_email with `String s -> Some s | `Null -> None in
-              version, stats_page, crash_email
-          | _ -> assert false)
-      with
-         Not_found -> default in
-    sth#finish ();
+      match rows with
+      | [row] -> row
+      | [] -> default
+      | _ -> assert false in
     settings := Some s;
     s
   in
@@ -64,24 +54,24 @@ let server_settings_version, server_settings_stats_page,
   let server_settings_version dbh =
     let (version, _, _) =
       match !settings with
-         None -> get_settings dbh
-       | Some settings -> settings in
+      | None -> get_settings dbh
+      | Some settings -> settings in
     version
   in
 
   let server_settings_stats_page dbh =
     let (_, stats_page, _) =
       match !settings with
-         None -> get_settings dbh
-       | Some settings -> settings in
+      | None -> get_settings dbh
+      | Some settings -> settings in
     stats_page
   in
 
   let server_settings_crash_email dbh =
     let (_, _, crash_email) =
       match !settings with
-         None -> get_settings dbh
-       | Some settings -> settings in
+      | None -> get_settings dbh
+      | Some settings -> settings in
     crash_email
   in
 
index 7939e74..5a3f5f3 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_strings.ml,v 1.2 2004/12/01 13:55:55 rich Exp $
+ * $Id: cocanwiki_strings.ml,v 1.3 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 open ExtString
 
 let string_contains substr str =
-  try String.find str substr; true
+  try ignore (String.find str substr); true
   with Invalid_string -> false
 
 let string_of_char = String.make 1
index e7189c7..56d2d06 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_template.ml,v 1.5 2005/11/24 14:54:15 rich Exp $
+ * $Id: cocanwiki_template.ml,v 1.6 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -77,70 +77,64 @@ let _get_template filename =
        Hashtbl.replace cache path (template, mtime);
        template
 
-let get_template ?page (dbh : Dbi.connection) hostid filename =
+let get_template ?page dbh hostid filename =
   let template = _get_template filename in
 
-  if hostid > 0 then (
+  if hostid > 0l then (
     (* Get standard fields concerning this host from the database. *)
-    let sth =
-      dbh#prepare_cached
+    let rows =
+      PGSQL(dbh) "nullable-results"
        "select h.theme_css, p.name, p.url, h.search_box,
                 h.brand, h.brand_tagline, h.brand_description,
                 h.pagebug
            from hosts h left outer join powered_by p on h.powered_by = p.id
-          where h.id = ?" in
-    sth#execute [`Int hostid];
+          where h.id = $hostid" in
 
     let theme_css, powered_by_name, powered_by_url, search_box,
       brand, brand_tagline, brand_description, pagebug =
-      match sth#fetch1 () with
-      | [ a; b; c; d; e; f; g; h] -> a, b, c, d, e, f, g, h
+      match rows with
+      | [ row ] -> row
       | _ -> assert false in
 
     let theme_css =
       match theme_css with
-      | `Null -> "/_css/standard.css"
-      | `String file -> file
-      | _ -> assert false in
+      | None -> "/_css/standard.css"
+      | Some file -> file in
 
     let powered_by_name, powered_by_url =
       match powered_by_name, powered_by_url with
-      | `Null, `Null ->
+      | None, None ->
          let url = "http://sandbox.merjis.com/" in
          let name = Cocanwiki_version.package ^ " " ^
                     Cocanwiki_version.version in
          name, url
-      | `String name, `String url -> name, url
+      | Some name, Some url -> name, url
       | _ -> assert false in
 
-    let search_box = match search_box with `Bool b -> b | _ -> assert false in
-
     let branding, brand,
       has_brand_tagline, brand_tagline,
       has_brand_description, brand_description =
       match brand with
-      | `Null -> false, "", false, "", false, ""
-      | `String brand ->
+      | None -> false, "", false, "", false, ""
+      | Some brand ->
          let has_brand_tagline, brand_tagline =
            match brand_tagline with
-           | `Null -> false, ""
-           | `String s -> true, s
-           | _ -> assert false in
+           | None -> false, ""
+           | Some s -> true, s in
          let has_brand_description, brand_description =
            match brand_description with
-           | `Null -> false, ""
-           | `String s -> true, s
-           | _ -> assert false in
+           | None -> false, ""
+           | Some s -> true, s in
          true, brand,
          has_brand_tagline, brand_tagline,
-         has_brand_description, brand_description
-      | _ -> assert false in
+         has_brand_description, brand_description in
 
     let has_pagebug, pagebug =
       match pagebug with
-      | `Null -> false, ""
-      | `String pagebug -> true, pagebug
-      | _ -> assert false in
+      | None -> false, ""
+      | Some pagebug -> true, pagebug in
+
+    let search_box = match search_box with Some b -> b | _ -> assert false in
 
     template#set "theme_css" theme_css;
     template#set "powered_by_name" powered_by_name;
@@ -156,9 +150,9 @@ let get_template ?page (dbh : Dbi.connection) hostid filename =
     template#set "pagebug" pagebug;
 
     (* Site menu. *)
-    let sth = dbh#prepare_cached "select url, label, ordering from sitemenu
-                                   where hostid = ? order by ordering" in
-    sth#execute [`Int hostid];
+    let rows = PGSQL(dbh)
+      "select url, label, ordering from sitemenu
+        where hostid = hostid order by ordering" in
 
     let is_homepage =
       match page with
@@ -167,18 +161,19 @@ let get_template ?page (dbh : Dbi.connection) hostid filename =
       | _ -> false in
     template#conditional "is_homepage" is_homepage;
 
-    let table = sth#map (function [`String url; `String label; _] ->
-                          let is_linked =
-                            match page with
-                            | None -> true
-                            | Some page when page = url -> false
-                            | _ -> true in
-                          let id = id_of_url url in
-                          [ "url", Template.VarString url;
-                            "label", Template.VarString label;
-                            "is_linked", Template.VarConditional is_linked;
-                            "id", Template.VarString id ]
-                        | _ -> assert false) in
+    let table = List.map
+      (fun (url, label, _) ->
+        let is_linked =
+          match page with
+          | None -> true
+          | Some page when page = url -> false
+          | _ -> true in
+        let id = id_of_url url in
+        [ "url", Template.VarString url;
+          "label", Template.VarString label;
+          "is_linked", Template.VarConditional is_linked;
+          "id", Template.VarString id ]
+      ) rows in
 
     template#table "sitemenu" table;
   )
index 21ebef2..cf8fdb3 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_template.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: cocanwiki_template.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,4 +25,4 @@ val _get_template : string -> Template.template
 (** Get template from filename, with host-specific substitutions.
   * The special ~page parameter is only used by [page.ml].
   *)
-val get_template : ?page:string -> Dbi.connection -> int -> string -> Template.template
+val get_template : ?page:string -> PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> Template.template
index 2016009..557d7a9 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: wikilib.ml,v 1.4 2005/11/11 09:39:21 rich Exp $
+ * $Id: wikilib.ml,v 1.5 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,7 +40,7 @@ type genurl_error_t = GenURL_OK of string
 
 let nontrivial_re = Pcre.regexp ~flags:[`CASELESS] "[a-z0-9]"
 
-let generate_url_of_title (dbh : Dbi.connection) hostid title =
+let generate_url_of_title dbh hostid title =
   (* Create a suitable URL from this title. *)
   let url =
     String.map (function
@@ -63,16 +63,12 @@ let generate_url_of_title (dbh : Dbi.connection) hostid title =
      * then it probably means that another page exists with similar enough
      * content, so we should redirect to there instead.
      *)
-    let sth = dbh#prepare_cached "select 1 from pages
-                                   where hostid = ? and url = ?" in
-    sth#execute [`Int hostid; `String url];
-
-    try
-      sth#fetch1int ();
-      GenURL_Duplicate url
-    with
-       Not_found ->
-         GenURL_OK url
+    let rows = PGSQL(dbh) "select 1 from pages
+                            where hostid = $hostid and url = $url" in
+    match rows with
+    | [Some 1l] -> GenURL_Duplicate url
+    | [] -> GenURL_OK url
+    | _ -> assert false
   )
 
 (* Obscure a mailto: URL against spammers. *)
@@ -119,8 +115,8 @@ let markup_link dbh hostid link =
   let url = Pcre.get_substring subs 1 in
 
   let tag name = function
-      `Null -> ""
-    | `String v -> " " ^ name ^ "=\"" ^ escape_html_tag v ^ "\""
+    | None -> ""
+    | Some v -> " " ^ name ^ "=\"" ^ escape_html_tag v ^ "\""
   in
 
   if Pcre.pmatch ~rex:image_re url then (
@@ -129,83 +125,91 @@ let markup_link dbh hostid link =
     let is_thumb = (Pcre.get_substring subs 1).[0] = 't' in
     let name = Pcre.get_substring subs 2 in
 
-    let sql = "select id, " ^
-             (if is_thumb then "tn_width, tn_height"
-              else "width, height") ^
-             ", alt, title, longdesc, class
-               from images
-              where hostid = ? and name = ?" in
-    let sth = dbh#prepare_cached sql in
-    sth#execute [`Int hostid; `String name];
+    let rows =
+      PGSQL(dbh)
+       "select id, width, height, tn_width, tn_height,
+               alt, title, longdesc, class
+           from images
+          where hostid = $hostid and name = $name" in
+
+    match is_thumb, rows with
+      (* [[image:...]] *)
+    | false, [imageid, width, height, _, _, alt, title, longdesc, clasz]
+      (* [[thumb:...]], but no thumbnail in the database - treat as image *)
+    | true, [imageid, width, height, None, None,
+            alt, title, longdesc, clasz] ->
+       let link = "/_image/" ^ escape_url name in
+
+       "<img src=\"" ^ link ^ "?version=" ^ Int32.to_string imageid ^
+         "\" width=\"" ^
+         Int32.to_string width ^
+         "\" height=\"" ^
+         Int32.to_string height ^
+         "\" alt=\"" ^
+         escape_html_tag alt ^
+         "\"" ^
+         tag "title" title ^
+         tag "longdesc" longdesc ^
+         tag "class" clasz ^
+         "/>"
+
+      (* [[thumb:...]] *)
+    | true, [imageid, _, _, Some tn_width, Some tn_height,
+            alt, title, longdesc, clasz] ->
+       let link = "/_image/" ^ escape_url name in
+       "<a href=\"" ^ link ^ "\">" ^
+         "<img src=\"" ^ link ^ "?version=" ^ Int32.to_string imageid ^
+         "&thumbnail=1" ^
+         "\" width=\"" ^
+         Int32.to_string tn_width ^
+         "\" height=\"" ^
+         Int32.to_string tn_height ^
+         "\" alt=\"" ^
+         escape_html_tag alt ^
+         "\"" ^
+         tag "title" title ^
+         tag "longdesc" longdesc ^
+         tag "class" clasz ^
+         "/>" ^
+         "</a>"
 
-    try
-      let imageid, width, height, alt, title, longdesc, clasz =
-       match sth#fetch1 () with
-           [`Int imageid; `Int width; `Int height; `String alt;
-            (`Null | `String _) as title;
-            (`Null | `String _) as longdesc;
-            (`Null | `String _) as clasz] ->
-             imageid, width, height, alt, title, longdesc, clasz
-         | _ -> assert false in
-
-      let link = "/_image/" ^ escape_url name in
-
-      (if is_thumb then "<a href=\"" ^ link ^ "\">" else "") ^
-      "<img src=\"" ^ link ^ "?version=" ^ string_of_int imageid ^
-      (if is_thumb then "&thumbnail=1" else "") ^
-      "\" width=\"" ^
-      string_of_int width ^
-      "\" height=\"" ^
-      string_of_int height ^
-      "\" alt=\"" ^
-      escape_html_tag alt ^
-      "\"" ^
-      tag "title" title ^
-      tag "longdesc" longdesc ^
-      tag "class" clasz ^
-      "/>" ^
-      (if is_thumb then "</a>" else "")
-    with
-       Not_found ->
-         (* Image not found. *)
-         "<a class=\"image_not_found\" " ^
+    (* no image found in the database *)
+    | _, [] ->
+       "<a class=\"image_not_found\" " ^
          "href=\"/_bin/upload_image_form.cmo?name=" ^
          escape_url name ^
          "\">" ^
          escape_html name ^
          "</a>"
+
+    (* image name is unique, so this shouldn't happen *)
+    | _, _ -> assert false
+
   ) else if Pcre.pmatch ~rex:file_re url then (
     (* It may be a file. *)
     let subs = Pcre.exec ~rex:file_re url in
     let name = Pcre.get_substring subs 1 in
 
-    let sth = dbh#prepare_cached "select title
-                                    from files
-                                   where hostid = ? and name = ?" in
-    sth#execute [`Int hostid; `String name];
-
-    try
-      let title =
-       match sth#fetch1 () with
-           [(`Null | `String _) as title] -> title
-         | _ -> assert false in
-
-      "<a href=\"/_file/" ^
-      escape_url name ^
-      "\"" ^
-      tag "title" title ^
-      ">" ^
-      escape_html name ^
-      "</a>"
-    with
-       Not_found ->
-         (* File not found. *)
-         "<a class=\"file_not_found\" " ^
+    let rows = PGSQL(dbh) "select title from files
+                            where hostid = $hostid and name = $name" in
+    match rows with
+    | [ title ] ->
+       "<a href=\"/_file/" ^
+         escape_url name ^
+         "\"" ^
+         tag "title" title ^
+         ">" ^
+         escape_html name ^
+         "</a>"
+    | [] ->
+       (* File not found. *)
+       "<a class=\"file_not_found\" " ^
          "href=\"/_bin/upload_file_form.cmo?name=" ^
          escape_url name ^
          "\">" ^
          escape_html name ^
          "</a>"
+    | _ -> assert false
   ) else (
     (* Pcre changed behaviour between versions.  Previously a non-capture
      * would return "".  Now it throws 'Not_found'.
@@ -231,37 +235,36 @@ let markup_link dbh hostid link =
        (* Look up the 'URL' against the titles in the database and
         * obtain the real URL.
         *)
-       let sth = dbh#prepare_cached "select url from pages
-                                       where hostid = ? and url is not null
-                                         and lower (title) = lower (?)" in
-       sth#execute [`Int hostid; `String url];
-
-       try
-         let url = sth#fetch1string () in
-         "/" ^ url, "internal", title
-       with
-           Not_found ->
-             (* It might be a template page ...  These pages don't
-              * exist in the template, but can be synthesized on the
-              * fly by page.ml.
+       let rows = PGSQL(dbh)
+         "select url from pages
+            where hostid = $hostid and url is not null
+              and lower (title) = lower ($url)" in
+
+       match rows with
+       | [Some url] ->
+           "/" ^ url, "internal", title
+       | [] ->
+           (* It might be a template page ...  These pages don't
+            * exist in the template, but can be synthesized on the
+            * fly by page.ml.
+            *)
+           let is_template_page url =
+             [] <> PGSQL(dbh)
+               "select 1 from templates
+                  where $url ~ url_regexp
+                  order by ordering
+                  limit 1"
+           in
+
+           if is_template_page url then
+             "/" ^ url, "internal", title
+           else
+             (* No, it really doesn't exist, so make it a link to
+              * a new page.
               *)
-             let is_template_page url =
-               let sth = dbh#prepare_cached "select 1 from templates
-                                               where ? ~ url_regexp
-                                               order by ordering
-                                               limit 1" in
-               sth#execute [`String url];
-
-               try sth#fetch1int () = 1 with Not_found -> false
-             in
-
-             if is_template_page url then
-               "/" ^ url, "internal", title
-             else
-               (* No, it really doesn't exist, so make it a link to
-                * a new page.
-                *)
              "/_bin/edit.cmo?title=" ^ escape_url url, "newpage", title
+
+       | _ -> assert false
       ) in
 
     "<a href=\"" ^ url ^
@@ -638,7 +641,7 @@ let preformatted_re = Pcre.regexp "^ (.*)"
 let html_open_re = Pcre.regexp "^<html>\\s*$"
 let html_close_re = Pcre.regexp "^</html>\\s*$"
 
-let xhtml_of_content (dbh : Dbi.connection) hostid text =
+let xhtml_of_content dbh hostid text =
   (* Split the text into lines. *)
   let lines = Pcre.split ~rex:split_lines_re text in
 
index 17ce9c8..d1b0c57 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: wikilib.mli,v 1.1 2004/10/21 11:42:05 rich Exp $
+ * $Id: wikilib.mli,v 1.2 2006/03/27 16:43:44 rich Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@ type genurl_error_t = GenURL_OK of string
                    | GenURL_BadURL
                    | GenURL_Duplicate of string
 
-val generate_url_of_title : Dbi.connection -> int -> string -> genurl_error_t
+val generate_url_of_title : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> genurl_error_t
 
-val xhtml_of_content : Dbi.connection -> int -> string -> string
+val xhtml_of_content : PGOCaml.pa_pg_data PGOCaml.t -> int32 -> string -> string
 
 val text_of_xhtml : string -> string