Index: /trunk/ippTools/src/releasetool.c
===================================================================
--- /trunk/ippTools/src/releasetool.c	(revision 34908)
+++ /trunk/ippTools/src/releasetool.c	(revision 34908)
@@ -0,0 +1,255 @@
+/*
+ * releasetool.c
+ *
+ * Copyright (C) 2013 IfA University of Hawaii
+ *
+ * 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 the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "pxtools.h"
+#include "pxdata.h"
+#include "pxchip.h"
+#include "pxspace.h"
+
+#include "releasetool.h"
+
+static bool definesurveyMode(pxConfig *config);
+static bool listsurveyMode(pxConfig *config);
+static bool definereleaseMode(pxConfig *config);
+static bool updatereleaseMode(pxConfig *config);
+static bool listreleaseMode(pxConfig *config);
+static bool definerelexpMode(pxConfig *config);
+static bool updaterelexpMode(pxConfig *config);
+static bool listrelexpMode(pxConfig *config);
+
+# define MODECASE(caseName, func) \
+    case caseName: \
+    if (!func(config)) { \
+        goto FAIL; \
+    } \
+    break;
+
+int main(int argc, char **argv) {
+    psLibInit(NULL);
+
+    pxConfig *config = releasetoolConfig(NULL, argc, argv);
+    if (!config) {
+        psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+        goto FAIL;
+    }
+
+    switch (config->mode) {
+        MODECASE(RELEASETOOL_MODE_DEFINESURVEY,     definesurveyMode);
+        MODECASE(RELEASETOOL_MODE_LISTSURVEY,       listsurveyMode);
+
+        MODECASE(RELEASETOOL_MODE_DEFINERELEASE,    definereleaseMode);
+        MODECASE(RELEASETOOL_MODE_UPDATERELEASE,    updatereleaseMode);
+        MODECASE(RELEASETOOL_MODE_LISTRELEASE,      listreleaseMode);
+
+        MODECASE(RELEASETOOL_MODE_DEFINERELEXP,     definerelexpMode);
+        MODECASE(RELEASETOOL_MODE_UPDATERELEXP,     updaterelexpMode);
+        MODECASE(RELEASETOOL_MODE_LISTRELEXP,       listrelexpMode);
+        default:
+            psAbort("invalid option (this should not happen)");
+    }
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(EXIT_SUCCESS);
+
+FAIL:
+    psErrorStackPrint(stderr, "\n");
+    int exit_status = pxerrorGetExitStatus();
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(exit_status);
+}
+
+static bool definesurveyMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool listsurveyMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool definereleaseMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool updatereleaseMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool listreleaseMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool definerelexpMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool updaterelexpMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+static bool listrelexpMode(pxConfig *config)
+{
+    psError(PS_ERR_UNKNOWN, true, "not yet implemented");
+    return false;
+}
+
+#ifdef notyet
+static bool defineskycellsMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_STR(inputFile, config->args, "-input", true, false);
+
+    unsigned int numBad = 0;
+    psMetadata *skycells = psMetadataConfigRead(NULL, &numBad, inputFile, false);
+    if (!skycells || numBad > 0) {
+        psError(PXTOOLS_ERR_UNKNOWN, false, "failed to read %s", inputFile);
+        return false;
+    }
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    psMetadataIterator *iter = psMetadataIteratorAlloc(skycells, PS_LIST_HEAD, NULL);
+
+    psMetadataItem *item;
+    int numSkycells = 0;
+    while ((item = psMetadataGetAndIncrement(iter))) {
+        if (item->type != PS_DATA_METADATA) {
+            psError(PS_ERR_UNKNOWN, true, "unexpected item in metadata type: %d", item->type);
+            return false;
+        }
+        psMetadata *md = item->data.md;
+        psString tess_id = psMetadataLookupStr(NULL, md, "tess_id");
+        psString skycell_id = psMetadataLookupStr(NULL, md, "skycell_id");
+
+        skycellRow *skycell = skycellObjectFromMetadata(md);
+        if (!skycell) {
+            psError(PS_ERR_UNKNOWN, false, "failed to create skycellRow from Metadata");
+            return false;
+        }
+
+        numSkycells++;
+        if (!skycellInsertObject(config->dbh, skycell)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to insert skycell %s %s", tess_id, skycell_id);
+            return false;
+        }
+    } 
+    psFree(iter);
+    psFree(skycells);
+
+   if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    psLogMsg("releasetool", PS_LOG_INFO, "%d skycells added", numSkycells);
+
+    return true;
+}
+static bool listMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_STR(config->args, where, "-skycell_id", "skycell.skycell_id", "LIKE");
+    PXOPT_COPY_STR(config->args, where, "-tess_id", "skycell.tess_id", "LIKE");
+    pxskycellAddWhere(config, where);
+
+    psString query = pxDataGet("releasetool_list.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (!psListLength(where->list)) {
+        psError(PXTOOLS_ERR_CONFIG, false, "search paramters are required\n");
+        psFree(where);
+        return false;
+    }
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(whereClause);
+
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    if (!psArrayLength(output)) {
+        psTrace("releasetool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (!ippdbPrintMetadatas(stdout, output, "skycell", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+
+    return true;
+}
+
+#endif
Index: /trunk/ippTools/src/releasetool.h
===================================================================
--- /trunk/ippTools/src/releasetool.h	(revision 34908)
+++ /trunk/ippTools/src/releasetool.h	(revision 34908)
@@ -0,0 +1,39 @@
+/*
+ * releasetool.h
+ *
+ * Copyright (C) 2013 University of Hawaii IFA 
+ *
+ * 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 the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef RELEASETOOL_H
+#define RELEASETOOL_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+    RELEASETOOL_MODE_NONE      = 0x0,
+    RELEASETOOL_MODE_DEFINESURVEY,
+    RELEASETOOL_MODE_LISTSURVEY,
+    RELEASETOOL_MODE_DEFINERELEASE,
+    RELEASETOOL_MODE_UPDATERELEASE,
+    RELEASETOOL_MODE_LISTRELEASE,
+    RELEASETOOL_MODE_DEFINERELEXP,
+    RELEASETOOL_MODE_UPDATERELEXP,
+    RELEASETOOL_MODE_LISTRELEXP,
+} releasetoolMode;
+
+pxConfig *releasetoolConfig(pxConfig *config, int argc, char **argv);
+
+#endif // RELEASETOOL_H
Index: /trunk/ippTools/src/releasetoolConfig.c
===================================================================
--- /trunk/ippTools/src/releasetoolConfig.c	(revision 34908)
+++ /trunk/ippTools/src/releasetoolConfig.c	(revision 34908)
@@ -0,0 +1,131 @@
+/*
+ * releasetoolConfig.c
+ *
+ * Copyright (C) 2012 IfA University of Hawaii
+ *
+ * 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 the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <psmodules.h>
+
+#include "pxtools.h"
+#include "pxspace.h"
+#include "releasetool.h"
+
+pxConfig *releasetoolConfig(pxConfig *config, int argc, char **argv)
+{
+    if (!config) {
+        config = pxConfigAlloc();
+    }
+
+    pmConfigReadParamsSet(false);
+
+    config->modules = pmConfigRead(&argc, argv, NULL);
+    if (! config->modules) {
+        psError(psErrorCodeLast(), false, "Can't find site configuration");
+        psFree(config);
+        return NULL;
+    }
+
+    // -definesurvey
+    psMetadata *definesurveyArgs = psMetadataAlloc();
+    psMetadataAddS32(definesurveyArgs, PS_LIST_TAIL, "-set_survey_id",   0, "define survey ID (required)", 0);
+    psMetadataAddStr(definesurveyArgs, PS_LIST_TAIL, "-set_survey_name", 0, "define survey name (required)", NULL);
+    psMetadataAddStr(definesurveyArgs, PS_LIST_TAIL, "-set_description", 0, "define survey description", NULL);
+
+    // -listsurvey
+    psMetadata *listsurveyArgs = psMetadataAlloc();
+    psMetadataAddStr(listsurveyArgs,  PS_LIST_TAIL, "-survey_name", 0, "search by survey name (LIKE comparision)", NULL);
+    psMetadataAddU64(listsurveyArgs,  PS_LIST_TAIL, "-limit",       0, "limit result set to N items", 0);
+    psMetadataAddBool(listsurveyArgs, PS_LIST_TAIL, "-simple",      0, "use the simple output format", false);
+
+    // -definerelease
+    psMetadata *definereleaseArgs = psMetadataAlloc();
+    psMetadataAddS32(definereleaseArgs, PS_LIST_TAIL, "-set_survey_id", 0,      "define survey ID (required)", 0);
+    psMetadataAddStr(definereleaseArgs, PS_LIST_TAIL, "-set_release_name", 0,   "define release name (required)", NULL);
+    psMetadataAddS32(definereleaseArgs, PS_LIST_TAIL, "-set_dataRelease", 0,    "define dataRelease", -1);
+    psMetadataAddStr(definereleaseArgs, PS_LIST_TAIL, "-set_state", 0,          "define survey state", NULL);
+
+    // -uptdaterelease
+    psMetadata *updatereleaseArgs = psMetadataAlloc();
+
+    // release_name and/or rel_id is required. This is handled in updatereleaseMode
+    psMetadataAddStr(updatereleaseArgs, PS_LIST_TAIL, "-release_name", 0,       "select by release name", NULL);
+    psMetadataAddS32(updatereleaseArgs, PS_LIST_TAIL, "-rel_id", 0,             "select by release ID", 0);
+
+    // Only support changing state for now
+    psMetadataAddStr(updatereleaseArgs, PS_LIST_TAIL, "-set_state", 0,          "define new survey state(required)", NULL);
+
+//    psMetadataAddS32(updatereleaseArgs, PS_LIST_TAIL, "-set_surveyID", 0,       "define surveyID (required)", 0);
+//    psMetadataAddStr(updatereleaseArgs, PS_LIST_TAIL, "-set_release_name", 0,    "define release name (required)", NULL);
+//    psMetadataAddS32(updatereleaseArgs, PS_LIST_TAIL, "-set_dataRelease", 0,    "define dataRelease", -1);
+
+
+    // -listrelease
+    psMetadata *listreleaseArgs = psMetadataAlloc();
+    psMetadataAddStr(listreleaseArgs,  PS_LIST_TAIL, "-survey_name", 0, "search by survey name (LIKE comparision)", NULL);
+    psMetadataAddStr(listreleaseArgs,  PS_LIST_TAIL, "-release_name", 0, "search by survey name (LIKE comparision)", NULL);
+    psMetadataAddStr(listreleaseArgs,  PS_LIST_TAIL, "-state",       0, "search by release state", NULL);
+    psMetadataAddU64(listreleaseArgs,  PS_LIST_TAIL, "-limit",       0, "limit result set to N items", 0);
+    psMetadataAddBool(listreleaseArgs, PS_LIST_TAIL, "-simple",      0, "use the simple output format", false);
+
+    psMetadata *definerelexpArgs = psMetadataAlloc();
+    psMetadataAddStr(definerelexpArgs,  PS_LIST_TAIL, "-release_name", 0, "search by survey name (LIKE comparision)", NULL);
+
+    psMetadata *updaterelexpArgs = psMetadataAlloc();
+    psMetadataAddStr(updaterelexpArgs,  PS_LIST_TAIL, "-release_name", 0, "search by survey name (LIKE comparision)", NULL);
+
+    psMetadata *listrelexpArgs = psMetadataAlloc();
+    psMetadataAddStr(listrelexpArgs,  PS_LIST_TAIL, "-release_name", 0, "search by survey name (LIKE comparision)", NULL);
+
+
+    psMetadata *argSets = psMetadataAlloc();
+    psMetadata *modes = psMetadataAlloc();
+
+    PXOPT_ADD_MODE("-definesurvey",     "define a survey",              RELEASETOOL_MODE_DEFINESURVEY,  definesurveyArgs);
+    PXOPT_ADD_MODE("-listsurvey",       "list skycell parameters",      RELEASETOOL_MODE_LISTSURVEY,    listsurveyArgs);
+    PXOPT_ADD_MODE("-definerelease",    "define a release",             RELEASETOOL_MODE_DEFINERELEASE, definereleaseArgs);
+    PXOPT_ADD_MODE("-updaterelease",    "update a release",             RELEASETOOL_MODE_UPDATERELEASE, updatereleaseArgs);
+    PXOPT_ADD_MODE("-listrelease",      "list releases",                RELEASETOOL_MODE_LISTRELEASE,   listreleaseArgs);
+    PXOPT_ADD_MODE("-definerelexp",     "define a released exposure",   RELEASETOOL_MODE_DEFINERELEXP,  definerelexpArgs);
+    PXOPT_ADD_MODE("-updaterelexp",     "update a released exposure",   RELEASETOOL_MODE_UPDATERELEXP,  updaterelexpArgs);
+    PXOPT_ADD_MODE("-listrelexp",       "list released exposures",      RELEASETOOL_MODE_LISTRELEXP,    listrelexpArgs);
+
+    if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+        psError(PS_ERR_UNKNOWN, false, "option parsing failed");
+        psFree(argSets);
+        psFree(modes);
+        psFree(config);
+        return NULL;
+    }
+
+    psFree(argSets);
+    psFree(modes);
+
+    // define Database handle, if used
+    config->dbh = psMemIncrRefCounter(pmConfigDB(config->modules));
+    if (!config->dbh) {
+        psError(PS_ERR_UNKNOWN, false, "Can't configure database");
+        psFree(config);
+        return NULL;
+    }
+
+    return config;
+}
