Index: /trunk/glueforge/templates/psdb/Makefile.am
===================================================================
--- /trunk/glueforge/templates/psdb/Makefile.am	(revision 6041)
+++ /trunk/glueforge/templates/psdb/Makefile.am	(revision 6042)
@@ -63,4 +63,6 @@
     popobject_c.tt \
     popobject_h.tt \
+    selectrowobjects.tt \
+    selectrowobjects_h.tt \
     selectrowsfits.tt \
     selectrowsfits_at.tt \
Index: /trunk/glueforge/templates/psdb/code.tt
===================================================================
--- /trunk/glueforge/templates/psdb/code.tt	(revision 6041)
+++ /trunk/glueforge/templates/psdb/code.tt	(revision 6042)
@@ -22,3 +22,4 @@
 [% INCLUDE metadatafromobject.tt %]
 [% INCLUDE objectfrommetadata.tt -%]
+[% INCLUDE selectrowobjects.tt -%]
 [% END -%]
Index: /trunk/glueforge/templates/psdb/header.tt
===================================================================
--- /trunk/glueforge/templates/psdb/header.tt	(revision 6041)
+++ /trunk/glueforge/templates/psdb/header.tt	(revision 6042)
@@ -27,4 +27,5 @@
 [% INCLUDE metadatafromobject_h.tt %]
 [% INCLUDE objectfrommetadata_h.tt -%]
+[% INCLUDE selectrowobjects_h.tt -%]
 [% END -%]
 
Index: /trunk/glueforge/templates/psdb/selectrowobjects.tt
===================================================================
--- /trunk/glueforge/templates/psdb/selectrowobjects.tt	(revision 6042)
+++ /trunk/glueforge/templates/psdb/selectrowobjects.tt	(revision 6042)
@@ -0,0 +1,33 @@
+psArray *[% table.namespace %]SelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, [% table.namespace FILTER upper %]_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // strip index column
+    for (i = 0; i < rowSet->n; i++) {
+        if (!psMetadataRemove((psMetadata *)rowSet->data[i], 0, [% table.namespace FILTER upper %]_INDEX_NAME)) {
+            psError(PS_ERR_UNKNOWN, true, "failed to remove item %s", [% table.namespace FILTER upper %]_INDEX_NAME);
+            psFree(rowSet);
+            return false;
+        }
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAlloc(rowSet->n);
+    returnSet->n = 0;
+
+    for (i = 0; i < rowSet->n; i++) {
+        psArrayAdd(returnSet, 0, [% table.namespace %]ObjectFromMetadata(rowSet->data[i]);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
Index: /trunk/glueforge/templates/psdb/selectrowobjects_h.tt
===================================================================
--- /trunk/glueforge/templates/psdb/selectrowobjects_h.tt	(revision 6042)
+++ /trunk/glueforge/templates/psdb/selectrowobjects_h.tt	(revision 6042)
@@ -0,0 +1,15 @@
+/** Selects up to limit rows from the database and returns them in a psArray
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+psArray *[% table.namespace %]SelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
