Ejemplo n.º 1
0
mz::JSON2SQLite::JSON2SQLite( const char* json, const char* ini, const char* db )
{
	mp_json = new mz::JSONParser( json );
	mp_ini = new mz::TableInfo( ini );
	ini_table = ((mz::TableInfo*)mp_ini);
	FillTableInfo();
}
Ejemplo n.º 2
0
/***********************************************************************
** FillTableDesc()
**
** This function will randomly fill in all the information needed in the
** TableDescription structure.
************************************************************************/
void FillTableDesc(TableDescription *TablePtr)
{
   TableInfo *TPtr;
   KeyDef *KPtr;
   ColumnInfo *CPtr;
   short i,j;
   short temp;
   short AbortColumn;
   short ZerosumColumn;
   short LastIdColumn;
   short Column[SQL_MAX_COLUMNS];
   short ColumnCount;
   short KeyLengthMax;
   short KeyLength;
   short ActualKeyColCount;

   TPtr=TablePtr->TableInfoPtr;

   /* build a list of all columns */
   for(i=0;i<TPtr->NumOfCol;i++) Column[i]=i;
   ColumnCount=TPtr->NumOfCol;

   /* if entry seq. or relative table then the key column is always */
   /* added by the system and is a system key and always column 0 */
   /* need to adjust the column count to allow for the addition of */
   /* a system key and still keep the same column count */
   if(TPtr->Organization==ENTRY_SEQ || TPtr->Organization==RELATIVE_TABLE){
      TPtr->KeyType=SYSTEM_KEY;
      ColumnCount--;
      }

   else {
      /* NOMAD cannot work with a key seq. table that has only a system */
      /* key so, make the key type either primary or clustering */
      if(RANDOM_T_OR_F) {
         TPtr->KeyType=PRIMARY_KEY;
         KeyLengthMax=255;
         }
      else {
         TPtr->KeyType=CLUSTERING_KEY;
         KeyLengthMax=247;
         }
      }

   /* Randomly pick a column to be a numeric data type for the abort column */
   temp=RANDOM_NUM0(ColumnCount-1);
   AbortColumn=Column[temp];
   CPtr=TPtr->ColPtr+AbortColumn;
   CPtr->DataType=RandomNumericType();

   /* if type is NUMERIC, DECIMAL, or PIC then make sure the length */
   /* and/or scale is set to a value NOMAD can use */
   if((CPtr->DataType==TYPE_NUMERIC)||(CPtr->DataType==TYPE_DECIMAL)){
      CPtr->DataTypeLen=RANDOM_RANGE(5,18);
      CPtr->DataTypeScale=0;
      }

   /* remove that column number from the list of column choices */
   for(i=temp;i+1<ColumnCount;i++) Column[i]=Column[i+1];
   ColumnCount--;

   /* Randomly pick a column to be a numeric data type for zerosum column */
   temp=RANDOM_NUM0(ColumnCount-1);
   ZerosumColumn=Column[temp];
   CPtr=TPtr->ColPtr+ZerosumColumn;
   CPtr->DataType=RandomNumericType();

   /* if type is NUMERIC, DECIMAL, or PIC then make sure the length */
   /* and/or scale is set to a value NOMAD can use */
   if((CPtr->DataType==TYPE_NUMERIC)||(CPtr->DataType==TYPE_DECIMAL)){
      CPtr->DataTypeLen=RANDOM_RANGE(5,18);
      CPtr->DataTypeScale=0;
      }

   /* remove that column number from the list of column choices */
   for(i=temp;i+1<ColumnCount;i++) Column[i]=Column[i+1];
   ColumnCount--;

   /* Randomly pick a column to be a numeric data type for last-id column */
   temp=RANDOM_NUM0(ColumnCount-1);
   LastIdColumn=Column[temp];
   CPtr=TPtr->ColPtr+LastIdColumn;
   CPtr->DataType=RandomNonDateTimeType();

   /* if type is NUMERIC, DECIMAL, PIC, CHAR, VCHAR, or PICX then make */
   /* sure the length and/or scale is set to a value NOMAD can use */
   if((CPtr->DataType==TYPE_NUMERIC)||
      (CPtr->DataType==TYPE_DECIMAL)||
      (CPtr->DataType==TYPE_CHAR)||
      (CPtr->DataType==TYPE_VARCHAR)){

      CPtr->DataTypeLen=RANDOM_RANGE(5,18);
      CPtr->DataTypeScale=0;
      }

   /* remove that column number from the list of column choices */
   for(i=temp;i+1<ColumnCount;i++) Column[i]=Column[i+1];
   ColumnCount--;

   /* if a key seq. table then we have some work to do to set up the */
   /* key field that NOMAD will use to keep track of records with */
   if(TPtr->Organization==KEY_SEQ){

      /* assign the key columns so that none of the three columns just picked */
      /* will be used as part of the key.  First, set up at least one */
      /* column of the key to meet NOMAD's requirements */
      /* make sure one of the key columns is a non-datetime type */
      KPtr=TPtr->KeyPtr;
      temp=RANDOM_NUM0(ColumnCount-1);
      KPtr->ColNum=Column[temp];
      CPtr=TPtr->ColPtr+(KPtr->ColNum);
      CPtr->DataType=RandomNonDateTimeType();
      for(j=temp;j+1<ColumnCount;j++) Column[j]=Column[j+1];
      ColumnCount--;
      KPtr++;

      /* if type is NUMERIC or DECIMAL, then make sure the length */
      /* and/or scale is set to a value NOMAD can use */
      if((CPtr->DataType==TYPE_NUMERIC)||
         (CPtr->DataType==TYPE_DECIMAL)||
         (CPtr->DataType==TYPE_CHAR)||
         (CPtr->DataType==TYPE_VARCHAR)){

         CPtr->DataTypeLen=RANDOM_RANGE(5,18);
         CPtr->DataTypeScale=0;
         }

      KeyLength=(short)CPtr->DataTypeLen;

      /* Now pick the rest of the key columns randomly */
      /* loop until we have the number of key columns we wanted or until */
      /* we run out of columns to choose from */
      ActualKeyColCount=1;
      i=1;
      while(KeyLengthMax!=(TPtr->KeyType==PRIMARY_KEY ? 255 : 247) &&
            (i<TPtr->KeyColCount) && (ColumnCount!=0)){
         temp=RANDOM_NUM0(ColumnCount);
         KPtr->ColNum=Column[temp];

         CPtr=TPtr->ColPtr+(KPtr->ColNum);
         FillColumnInfo(CPtr);

         /* see if this key column will make the total key length exceed */
         /* the maximum key length.  If it doesn't then we can use this one */
         /* for part of the key.  If it does, then randomly make up another */
         /* set of column information until we get one we can use */
         while(KeyLength+(CPtr->DataTypeLen) > KeyLengthMax){

            /* clear column info */
            memset(CPtr,-1,sizeof(ColumnInfo));
            CPtr->CName[0]          = NULL;
            CPtr->Literal           = NULL;
            CPtr->CHeading[0]       = NULL;

            /* Randomly create new column info */
            FillColumnInfo(CPtr);
            }
         ActualKeyColCount++;
         KeyLength+=(short)CPtr->DataTypeLen;

         /* remove it from the list of column choices */
         for(j=temp;j+1<ColumnCount;j++) Column[j]=Column[j+1];
         ColumnCount--;

         KPtr++;
         i++;
         } /* end: while */

      /* it might have been the case that we could not select the requested */
      /* number of key columns because the maximum key length would have */
      /* been exceeded no matter which combination of columns were chosen */
      /* So, we'll adjust the key column count here to be the actual count */
      TPtr->KeyColCount=ActualKeyColCount;

      } /* end: if KEY_SEQ */

   /* Now just fill in the TableInfo part.  The NomadInfo */
   /* will be filled in later by CreateSQLTable() */
   FillTableInfo(TablePtr->TableInfoPtr);

   } /* end: FillTableDesc() */
Ejemplo n.º 3
0
/********************************************************************
** FindRequiredColumns()
**
** This function finds the required column numbers for the three
** required columns in an SQL table (in addition to any key columns).
** The three columns can be of any SQL data type EXCEPT date-time and
** can NOT be a key column.  The three columns are ZEROSUM, ABORT, and
** LAST PROCESS ID and are used for consistency checking and problem
** analysis.  While the key may be composed of several columns, there is
** the requirement that at least one column of the key MUST not be a
** date-time SQL data type and have a scale of 5 or greater.
**
** Input:
**    - TableDescription
********************************************************************/
ReturnStatus *FindRequiredColumns(TableDescription *table_ptr)
{
   short key_column[SQL_MAX_KEY_COLUMNS];
   TableInfo *TPtr;
   NomadInfo *NPtr;
   ReturnStatus *RSPtr;
   short column_number;
   short temp_size;
   Boolean done;
   key_info *tptr_key;
   short temp_data_type;
   short i;
   short memory_required;
   short unknown; /* counter for key column data types */


   /* initialize some pointers to save typing in long pointer names */
   TPtr=table_ptr->TableInfoPtr;
   NPtr=table_ptr->NomadInfoPtr;
   RSPtr=NULL;

   switch(TPtr->Organization){
      case RELATIVE_TABLE:
         NPtr->key_column_used=0;
         NPtr->key_column_count=1;
         NPtr->key_ptr=(key_info *)malloc(sizeof(key_info));
         if(NPtr->key_ptr==NULL) return(BuildReturnStatusMALLOC);
         NPtr->key_ptr->ColNum=0;
			memory_required=(short)TPtr->ColPtr[0].DataTypeLen;
         NPtr->key_ptr->DefaultValue=(char *)malloc(memory_required);
         if(NPtr->key_ptr->DefaultValue==NULL) return(BuildReturnStatusMALLOC);
         break;
      case ENTRY_SEQ:
         NPtr->key_column_used=
            ScanTableColumnsForNondatetime(TPtr,0);
         NPtr->key_column_count=1;
         NPtr->key_ptr=(key_info *)malloc(sizeof(key_info));
         if(NPtr->key_ptr==NULL) return(BuildReturnStatusMALLOC);
         NPtr->key_ptr->ColNum=NPtr->key_column_used;
			memory_required=(short)TPtr->ColPtr[NPtr->key_column_used].DataTypeLen;
         NPtr->key_ptr->DefaultValue=(char *)malloc(memory_required);
         if(NPtr->key_ptr->DefaultValue==NULL) return(BuildReturnStatusMALLOC);
         break;
      case KEY_SEQ:

			NPtr->key_column_count=TPtr->KeyColCount;
         for(i=0;i<NPtr->key_column_count;i++){
				key_column[i]=TPtr->KeyPtr[i].ColNum;
				}

         /* remove SYSKEY column from our key column list if it is there */
         /* because we ignore it when dealing with key sequenced tables */
         /* the SYSKEY column is always the first column of a table */
         /* SYSKEY is also the least significant key column of a clustering key */
         if((TPtr->KeyType==CLUSTERING_KEY) ||
            (TPtr->KeyType==SYSTEM_KEY)){
            for(i=0;i+1<NPtr->key_column_count;i++){
               key_column[i]=key_column[i+1];
               }
            NPtr->key_column_count--;
            }
			// check that we have at least one non-SYSKEY key to proceed
			if(NPtr->key_column_count<=0){
		      RSPtr=BuildReturnStatus(RT_PROGRAMERR,0,NULL,
		         "%s need at least one primary key column (other than SYSKEY) in '%s'.\n",
		         g_errstr,TPtr->TableName);
		      return(RSPtr);
			}

         /* allocate space for key column numbers */
         temp_size=NPtr->key_column_count*sizeof(key_info);
         NPtr->key_ptr=(key_info *)malloc(temp_size);
         if(NPtr->key_ptr==NULL) return(BuildReturnStatusMALLOC);

         /* set column numbers of key columns into TableDescription structure */
         unknown=0;
         NPtr->key_column_used=-1;
         tptr_key=NPtr->key_ptr;
         FillTableInfo(TPtr);

         for(i=0;i<NPtr->key_column_count;i++){
            tptr_key->ColNum=key_column[i];
				temp_data_type=TPtr->ColPtr[key_column[i]].pTypeInfo->SQLDataType;
				memory_required=(short)TPtr->ColPtr[key_column[i]].DataTypeLen;

            /* pick a key column to use as our record number key */
            /* NOTE: can NOT be a datetime data type and must be able to hold...*/
            /* ... a five digit value if any other SQL data type */
            /* The FIRST key column which meets our requirements will be chosen */
				switch(temp_data_type){

					case SQL_INTEGER:
					case SQL_SMALLINT:
					case SQL_FLOAT:
					case SQL_REAL:
					case SQL_DOUBLE:
					case SQL_BIGINT:
						if(NPtr->key_column_used==-1){
							NPtr->key_column_used=key_column[i];
							}
						break;

					case SQL_NUMERIC:
					case SQL_DECIMAL:
						if(TPtr->ColPtr[key_column[i]].DataTypePrecision>=5){
							if(NPtr->key_column_used==-1){
								NPtr->key_column_used=key_column[i];
								}
							}
						break;

					case SQL_CHAR:
					case SQL_VARCHAR:
					case SQL_LONGVARCHAR:
						if(TPtr->ColPtr[key_column[i]].DataTypeLen>=5){
							if(NPtr->key_column_used==-1){
								NPtr->key_column_used=key_column[i];
								}
							}
						memory_required++;	// add byte for NULL terminator
						break;

					case SQL_BINARY:
					case SQL_VARBINARY:
					case SQL_LONGVARBINARY:
						if(TPtr->ColPtr[key_column[i]].DataTypeLen>=5){
							if(NPtr->key_column_used==-1){
								NPtr->key_column_used=key_column[i];
								}
							}
						break;

					// These types can't be used for the record number key column
					case SQL_DATE:
					case SQL_TIME:
					case SQL_TIMESTAMP:
					case SQL_TINYINT:
					case SQL_BIT:

					/* an unknown data type */
					default:
						unknown++;

					} /* end switch */

				/* allocate space for the constant value used for key columns */
            /* in the case of more than one column in the key.  We will select */
            /* one column to use and the others will have a fixed value */
            tptr_key->DefaultValue=(char *)malloc(memory_required);
            if(tptr_key->DefaultValue==NULL) return(BuildReturnStatusMALLOC);

            /* save a random fixed value to use for this key column */
            memcpy(tptr_key->DefaultValue,
                   TPtr->ColPtr[key_column[i]].Value.pChar,
                   memory_required);
            tptr_key++;
            }
            break;
      } /* end: switch on file type */

   /* check that we found a key column to use that met our requirements */
   if(NPtr->key_column_used<=-1){
      RSPtr=BuildReturnStatus(RT_PROGRAMERR,0,NULL,
         "%s ONE column of the key MUST meet these requirements:\n"
         "        o  NOT be an SQL date-time or interval data type\n"
         "        o  if NUMERIC or DECIMAL it MUST have precision >= 5\n"
         "        o  if any CHAR or BINARY types it MUST have length >= 5\n"
         "   Hey, who knows why...ask my boss...at any rate I wasn't able to find\n"
         "   a column within the key of table '%s'\n"
         "   that met all those lofty requirements.\n"
         "   I know you already know what this means but, I'm going to tell you\n"
         "   anyway, just to make it official: 'I can't use this table'\n"
         "   Change the key for this table or give me another table\n\n",
         g_errstr,TPtr->TableName);
      return(RSPtr);
      }

   /* scan fields looking for 16 bit (or larger) short field to be zerosum */
   column_number=0;
   done=FALSE;
	column_number=ScanTableColumnsForNumber(TPtr,column_number);
   while((!done) && (column_number>=0)) {

      /* make sure the column is large enough to hold the zerosum values */
      if(TPtr->ColPtr[column_number].DataTypePrecision>=5){

         /* make sure its not one of the columns of the key */
         if(is_key_column(table_ptr,column_number)) {
         	column_number++;
				column_number=ScanTableColumnsForNumber(TPtr,column_number);
      	   }
         else done=TRUE;
         }
      else {
      	column_number++;
      	column_number=ScanTableColumnsForNumber(TPtr,column_number);
	      }
      }

   if(column_number<0){
      RSPtr=BuildReturnStatus(RT_PROGRAMERR,0,NULL,
         "%s unable to find two numeric columns and one non-datetime\n"
         "   column that are not part of the key\n",
         g_errstr);
      return(RSPtr);
      }

   NPtr->zerosum_column=column_number;


   /* scan fields looking for 16 bit (or larger) short field to be abort */
   column_number=0;
   done=FALSE;
	column_number=ScanTableColumnsForNumber(TPtr,column_number);
   while(!done) {

		/* make sure its not one of the columns of the key or zerosum */
      if((is_key_column(table_ptr,column_number))||
         (column_number==NPtr->zerosum_column)){
				column_number++;
				column_number=ScanTableColumnsForNumber(TPtr,column_number);
            }
      else done=TRUE;
      }

   if(column_number<0){
      RSPtr=BuildReturnStatus(RT_PROGRAMERR,0,NULL,
         "%s unable to find two numeric columns and one non-datetime\n"
         "   column that are not part of the key\n",
         g_errstr);
      return(RSPtr);
      }

   NPtr->abort_column=column_number;


   /* scan fields looking for any non-date-time column to be process-id */
   column_number=0;
   done=FALSE;
	column_number=ScanTableColumnsForNumber(TPtr,column_number);
   while(!done) {

      /* make sure its not one of the columns of the key, zerosum, or ...*/
      /*...abort columns */
      if((is_key_column(table_ptr,column_number))||
         (column_number==NPtr->zerosum_column)||
         (column_number==NPtr->abort_column)){
            column_number++;
				column_number=ScanTableColumnsForNumber(TPtr,column_number);
            }
      else done=TRUE;
      }

   if(column_number<0){
      RSPtr=BuildReturnStatus(RT_PROGRAMERR,0,NULL,
         "%s unable to find three numeric columns that are not part of the key\n",
         g_errstr);
      return(RSPtr);
      }
   NPtr->last_process_id_column=column_number;

   return(NULL);
   } /* end: FindRequiredColumns() */