Index: trunk/glueforge/templates/psdb/Makefile.am
===================================================================
--- trunk/glueforge/templates/psdb/Makefile.am	(revision 8169)
+++ trunk/glueforge/templates/psdb/Makefile.am	(revision 8201)
@@ -68,6 +68,12 @@
     popobject_c.tt \
     popobject_h.tt \
+    printmetadata.tt \
+    printmetadata_h.tt \
+    printmetadataraw.tt \
+    printmetadataraw_h.tt \
     printmetadatas.tt \
     printmetadatas_h.tt \
+    printmetadatasraw.tt \
+    printmetadatasraw_h.tt \
     printobjects.tt \
     printobjects_h.tt \
Index: trunk/glueforge/templates/psdb/code.tt
===================================================================
--- trunk/glueforge/templates/psdb/code.tt	(revision 8169)
+++ trunk/glueforge/templates/psdb/code.tt	(revision 8201)
@@ -3,7 +3,8 @@
 #include "[% pkg_name %].h"
 
+#define [% pkg_name FILTER upper %]_DEFAULT_INDEX_NAME "position"
 [% FOREACH table = tables -%]
 #define [% table.namespace FILTER upper %]_TABLE_NAME "[% table.name %]"
-#define [% table.namespace FILTER upper %]_INDEX_NAME "position"
+#define [% table.namespace FILTER upper %]_INDEX_NAME [% pkg_name FILTER upper %]_DEFAULT_INDEX_NAME
 [% END -%]
 #define MAX_STRING_LENGTH 1024
@@ -11,5 +12,8 @@
 [% INCLUDE init.tt %]
 [% INCLUDE cleanup.tt %]
+[% INCLUDE printmetadata.tt %]
+[% INCLUDE printmetadataraw.tt %]
 [% INCLUDE printmetadatas.tt %]
+[% INCLUDE printmetadatasraw.tt %]
 [% FOREACH table = tables -%]
 [% INCLUDE alloc.tt %]
Index: trunk/glueforge/templates/psdb/header.tt
===================================================================
--- trunk/glueforge/templates/psdb/header.tt	(revision 8169)
+++ trunk/glueforge/templates/psdb/header.tt	(revision 8201)
@@ -13,5 +13,8 @@
 [% INCLUDE init_h.tt %]
 [% INCLUDE cleanup_h.tt %]
+[% INCLUDE printmetadata_h.tt %]
+[% INCLUDE printmetadataraw_h.tt %]
 [% INCLUDE printmetadatas_h.tt %]
+[% INCLUDE printmetadatasraw_h.tt %]
 [% FOREACH table = tables -%]
 [% INCLUDE object_h.tt %]
Index: trunk/glueforge/templates/psdb/printmetadata.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadata.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadata.tt	(revision 8201)
@@ -0,0 +1,21 @@
+bool [% pkg_namespace %]PrintMetadata(FILE *stream, psMetadata *md, bool mdconfigformat)
+{
+    PS_ASSERT_PTR_NON_NULL(md, false);
+
+    psMetadata *clean = psMetadataCopy(NULL, md);
+
+    // don't bother to check the return status as the key we are trying to
+    // remove may or may not be there
+    // XXX someday psErr should be checked -- the only acceptable error is key
+    // not found
+    psMetadataRemoveKey(clean, [% pkg_name FILTER upper %]_DEFAULT_INDEX_NAME);
+    
+    if (![% pkg_namespace %]PrintMetadataRaw(stream, clean, mdconfigformat)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(clean);
+        return false;
+    }
+    psFree(clean);
+
+    return true;
+}
Index: trunk/glueforge/templates/psdb/printmetadata_h.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadata_h.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadata_h.tt	(revision 8201)
@@ -0,0 +1,15 @@
+/** Formats and prints a metadata
+ *
+ * Any internal use fields are stripped.
+ *
+ * When mdconfigformat is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool [% pkg_namespace %]PrintMetadata(
+    FILE            *stream,            ///< a stream
+    psMetadata      *md,                ///< An array of metadata
+    bool            mdconfigformat      ///< format as mdconfig or simple
+);
Index: trunk/glueforge/templates/psdb/printmetadataraw.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadataraw.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadataraw.tt	(revision 8201)
@@ -0,0 +1,13 @@
+bool [% pkg_namespace %]PrintMetadataRaw(FILE *stream, psMetadata *md, bool mdconfigformat)
+{
+    PS_ASSERT_PTR_NON_NULL(md, false);
+
+    psString str = psMetadataConfigFormat(md);
+    if (!str) {
+        psError(PS_ERR_UNKNOWN, false, "failed to format data into a string");
+    }
+    fprintf(stream, "%s\n", str);
+    psFree(str);
+
+    return true;
+}
Index: trunk/glueforge/templates/psdb/printmetadataraw_h.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadataraw_h.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadataraw_h.tt	(revision 8201)
@@ -0,0 +1,15 @@
+/** Formats and prints a metadata
+ *
+ * The metadata is printed verbatium without removing any fields.
+ *
+ * When mdconfigformat is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool [% pkg_namespace %]PrintMetadataRaw(
+    FILE            *stream,            ///< a stream
+    psMetadata      *md,                ///< An array of metadata
+    bool            mdconfigformat      ///< format as mdconfig or simple
+);
Index: trunk/glueforge/templates/psdb/printmetadatas.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadatas.tt	(revision 8169)
+++ trunk/glueforge/templates/psdb/printmetadatas.tt	(revision 8201)
@@ -4,30 +4,12 @@
     PS_ASSERT_PTR_NON_NULL(mdname, false);
 
-    psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(mds); i++) {
         psMetadata *md = mds->data[i];
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            mdname,
-            PS_META_DUPLICATE_OK,
-            NULL,
-            md
-        )) {
-            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
-            psFree(output);
+        if (![% pkg_namespace %]PrintMetadata(stream, md, mdconfigformat)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
             return false;
         }
     }
 
-    psString str = psMetadataConfigFormat(output);
-    if (!str) {
-        psError(PS_ERR_UNKNOWN, false, "failed to format data into a string");
-        psFree(output);
-    }
-    psFree(output);
-    fprintf(stream, "%s\n", str);
-    psFree(str);
-
     return true;
 }
Index: trunk/glueforge/templates/psdb/printmetadatas_h.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadatas_h.tt	(revision 8169)
+++ trunk/glueforge/templates/psdb/printmetadatas_h.tt	(revision 8201)
@@ -1,3 +1,5 @@
 /** Formats and prints an array of metadata
+ *
+ * Any internal use fields are stripped.
  *
  * When mdconfigformat is set the formated output is in psMetadataConfig
Index: trunk/glueforge/templates/psdb/printmetadatasraw.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadatasraw.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadatasraw.tt	(revision 8201)
@@ -0,0 +1,15 @@
+bool [% pkg_namespace %]PrintMetadatasRaw(FILE *stream, psArray *mds, const char *mdname, bool mdconfigformat)
+{
+    PS_ASSERT_PTR_NON_NULL(mds, false);
+    PS_ASSERT_PTR_NON_NULL(mdname, false);
+
+    for (long i = 0; i < psArrayLength(mds); i++) {
+        psMetadata *md = mds->data[i];
+        if (![% pkg_namespace %]PrintMetadataRaw(stream, md, mdconfigformat)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+            return false;
+        }
+    }
+
+    return true;
+}
Index: trunk/glueforge/templates/psdb/printmetadatasraw_h.tt
===================================================================
--- trunk/glueforge/templates/psdb/printmetadatasraw_h.tt	(revision 8201)
+++ trunk/glueforge/templates/psdb/printmetadatasraw_h.tt	(revision 8201)
@@ -0,0 +1,16 @@
+/** Formats and prints an array of metadata
+ *
+ * The metadatas are printed verbatium without removing any fields.
+ *
+ * When mdconfigformat is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool [% pkg_namespace %]PrintMetadatasRaw(
+    FILE            *stream,            ///< a stream
+    psArray         *mds,               ///< An array of metadata
+    const char      *mdname,            ///< name of the metadata(s)
+    bool            mdconfigformat      ///< format as mdconfig or simple
+);
