Index: /trunk/Ohana/src/tools/src/fits_to_mysql.c
===================================================================
--- /trunk/Ohana/src/tools/src/fits_to_mysql.c	(revision 38997)
+++ /trunk/Ohana/src/tools/src/fits_to_mysql.c	(revision 38998)
@@ -34,5 +34,6 @@
   TYPE_INT64, 
   TYPE_FLOAT, 
-  TYPE_DOUBLE
+  TYPE_DOUBLE,
+  TYPE_SEQUENCE,
 } TypeInt;
 
@@ -53,4 +54,7 @@
 char        *TABLENAME;
 char        *TABLEPREFIX;
+char        *TABLESUFFIX;
+char        *SEQUENCE_COLUMN;
+int          SEQUENCE_COLUMN_START;
 
 int args (int *argc, char **argv);
@@ -60,5 +64,5 @@
 ColumnDef *parse_table (Header *header, int *ncolumn);
 int create_table (ColumnDef *columns, int Ncolumns, char *extname, IOBuffer *insert, MYSQL *mysql);
-void write_data (ColumnDef *columns, int Ncolumns, FTable *table, IOBuffer *insert, MYSQL *mysql);
+void write_data (ColumnDef *columns, int Ncolumns, int start, FTable *table, IOBuffer *insert, MYSQL *mysql);
 
 void *gfits_get_bintable_column_data_by_Ncol (FTable *table, int Nfield, char *type, off_t *Nrow, int *Ncol, char nativeOrder);
@@ -167,5 +171,5 @@
       fprintf (stderr, "read "OFF_T_FMT" rows\n", header.Naxis[1]);
 
-      write_data (columns, Ncolumns, &table, &insert, mysqlReal);
+      write_data (columns, Ncolumns, start, &table, &insert, mysqlReal);
 
       start += Nrows;
@@ -195,4 +199,6 @@
   FREE (TABLENAME);
   FREE (TABLEPREFIX);
+  FREE (TABLESUFFIX);
+  FREE (SEQUENCE_COLUMN);
 
   ohana_memdump (TRUE);
@@ -228,4 +234,17 @@
   int Nfields;
   if (!gfits_scan (header, "TFIELDS", "%d", 1, &Nfields)) return NULL;
+
+  // generate the sequence column first so that any actual table columns which match the
+  // requested name get a uniquified colname
+  if (SEQUENCE_COLUMN) {
+    column[Ncolumn].colname = strcreate (SEQUENCE_COLUMN);
+    column[Ncolumn].rawname = strcreate (SEQUENCE_COLUMN);
+    column[Ncolumn].format = NULL;
+    replace_dot_with_underscore (column[Ncolumn].colname);
+    column[Ncolumn].Nval = 0;
+    column[Ncolumn].Nbytes = 0;
+    column[Ncolumn].type = TYPE_SEQUENCE;
+    Ncolumn++;
+  }
 
   // first, extract the table data:
@@ -311,13 +330,15 @@
 
   char *tablename = NULL;
-  if (TABLEPREFIX) {
-    if (TABLENAME) {
-      strextend (&tablename, "%s%s", TABLEPREFIX, TABLENAME);
-    } else {
-      strextend (&tablename, "%s%s", TABLEPREFIX, extname);
-    }
+  int length = TABLENAME ? strlen(TABLENAME) : strlen(extname);
+  if (TABLEPREFIX) length += strlen(TABLEPREFIX);
+  if (TABLESUFFIX) length += strlen(TABLESUFFIX);
+  ALLOCATE_ZERO (tablename, char, length + 1);
+  if (TABLEPREFIX) strcpy (tablename, TABLEPREFIX);
+  if (TABLENAME) {
+    strcat (tablename, TABLENAME);
   } else {
-    tablename = TABLENAME ? strcreate (TABLENAME) : strcreate (extname);
-  }
+    strcat (tablename, extname);
+  }
+  if (TABLESUFFIX) strcat (tablename, TABLESUFFIX);
   replace_dot_with_underscore (tablename);
 
@@ -374,4 +395,8 @@
 	PrintIOBuffer (&buffer, "%s VARCHAR(%d)", columns[i].colname, columns[i].Nval);
 	break;
+      case TYPE_SEQUENCE:
+	// SEQUENCE is a (single) special column with a sequence of values from SEQUENCE_COLUMN_START
+	PrintIOBuffer (&buffer, "%s INT", columns[i].colname);
+	break;
       default:
 	myAbort ("oops");
@@ -415,5 +440,5 @@
 }
 
-void write_data (ColumnDef *columns, int Ncolumns, FTable *table, IOBuffer *insert, MYSQL *mysql) {
+void write_data (ColumnDef *columns, int Ncolumns, int start, FTable *table, IOBuffer *insert, MYSQL *mysql) {
 
   int i, j, Nf;
@@ -429,10 +454,16 @@
 
   // first, extract the table data: (probably should save this structure and re-use in create_table)
+  int Nfield = 1;
   for (i = 0; i < Ncolumns; i++) {
     off_t Nrow;
     int Ncol;
     char type[16];
-    data[i] = gfits_get_bintable_column_data_by_Ncol (table, i + 1, type, &Nrow, &Ncol, FALSE);
-    myAssert (Nrow == Ny, "oops");
+
+    // we need to skip past virtual columns that do not correspond to actual table columns
+    if (columns[i].type == TYPE_SEQUENCE) { data[i] = NULL; continue; }
+    data[i] = gfits_get_bintable_column_data_by_Ncol (table, Nfield, type, &Nrow, &Ncol, FALSE);
+    Nfield ++;
+    myAssert (Ncol == columns[i].Nval, "oops (1)");
+    myAssert (Nrow == Ny, "oops (2)");
   }
 
@@ -444,4 +475,8 @@
     for (Nf = 0; Nf < Ncolumns; Nf++) {
       switch (columns[Nf].type) {
+	case TYPE_SEQUENCE:
+	  // XXX need to include offset from table block and possible starting offset
+	  PrintIOBuffer (&output, "%d", i + start + SEQUENCE_COLUMN_START);
+	  break;
 	case TYPE_CHAR: {
 	  char line[1024];
@@ -719,4 +754,23 @@
     remove_argument (N, argc, argv);
   }
+  TABLESUFFIX = NULL;
+  if ((N = get_argument (*argc, argv, "-tablesuffix"))) {
+    remove_argument (N, argc, argv);
+    TABLESUFFIX = strcreate (argv[N]);
+    remove_argument (N, argc, argv);
+  }
+
+  SEQUENCE_COLUMN = NULL;
+  if ((N = get_argument (*argc, argv, "-sequence-column"))) {
+    remove_argument (N, argc, argv);
+    SEQUENCE_COLUMN = strcreate (argv[N]);
+    remove_argument (N, argc, argv);
+  }
+  SEQUENCE_COLUMN_START = 0;
+  if ((N = get_argument (*argc, argv, "-sequence-column-start"))) {
+    remove_argument (N, argc, argv);
+    SEQUENCE_COLUMN_START = atoi (argv[N]);
+    remove_argument (N, argc, argv);
+  }
 
   return TRUE;
