Example #1
0
static int
vtxt_column (sqlite3_vtab_cursor * pCursor, sqlite3_context * pContext,
	     int column)
{
/* fetching value for the Nth column */
    int nCol = 1;
    int i;
    char buf[4096];
    int type;
    const char *value;
    VirtualTextCursorPtr cursor = (VirtualTextCursorPtr) pCursor;
    gaiaTextReaderPtr text = cursor->pVtab->reader;
    if (column == 0)
      {
	  /* the ROWNO column */
	  sqlite3_result_int (pContext, cursor->current_row);
	  return SQLITE_OK;
      }
    if (text->current_line_ready == 0)
	return SQLITE_ERROR;
    for (i = 0; i < text->max_fields; i++)
      {
	  if (nCol == column)
	    {
		if (!gaiaTextReaderFetchField (text, i, &type, &value))
		    sqlite3_result_null (pContext);
		else
		  {
		      if (type == VRTTXT_INTEGER)
			{
			    strcpy (buf, value);
			    text_clean_integer (buf);
#if defined(_WIN32) || defined(__MINGW32__)
/* CAVEAT - M$ runtime has non-standard functions for 64 bits */
			    sqlite3_result_int64 (pContext, _atoi64 (buf));
#else
			    sqlite3_result_int64 (pContext, atoll (buf));
#endif
			}
		      else if (type == VRTTXT_DOUBLE)
			{
			    strcpy (buf, value);
			    text_clean_double (buf);
			    sqlite3_result_double (pContext, atof (buf));
			}
		      else if (type == VRTTXT_TEXT)
			  sqlite3_result_text (pContext, value, strlen (value),
					       free);
		      else
			  sqlite3_result_null (pContext);
		  }
	    }
	  nCol++;
      }
    return SQLITE_OK;
}
Example #2
0
static int
vtxt_eval_constraints (VirtualTextCursorPtr cursor)
{
/* evaluating Filter constraints */
    int nCol;
    int i;
    char buf[4096];
    int type;
    const char *value = NULL;
    sqlite3_int64 int_value;
    double dbl_value;
    char *txt_value = NULL;
    int is_int = 0;
    int is_dbl = 0;
    int is_txt = 0;
    gaiaTextReaderPtr text = cursor->pVtab->reader;
    VirtualTextConstraintPtr pC;
    if (text->current_line_ready == 0)
	return SQLITE_ERROR;
    pC = cursor->firstConstraint;
    while (pC)
      {
	  int ok = 0;
	  if (pC->iColumn == 0)
	    {
		/* the ROWNO column */
		int_value = cursor->current_row;
		is_int = 1;
		goto eval;
	    }
	  nCol = 1;
	  for (i = 0; i < text->max_fields; i++)
	    {
		is_int = 0;
		is_dbl = 0;
		is_txt = 0;
		if (nCol == pC->iColumn)
		  {

		      if (!gaiaTextReaderFetchField (text, i, &type, &value))
			  ;
		      else
			{
			    if (type == VRTTXT_INTEGER)
			      {
				  strcpy (buf, value);
				  text_clean_integer (buf);
#if defined(_WIN32) || defined(__MINGW32__)
/* CAVEAT - M$ runtime has non-standard functions for 64 bits */
				  int_value = _atoi64 (buf);
#else
				  int_value = atoll (buf);
#endif
				  is_int = 1;
			      }
			    else if (type == VRTTXT_DOUBLE)
			      {
				  strcpy (buf, value);
				  text_clean_double (buf);
				  dbl_value = atof (buf);
				  is_dbl = 1;
			      }
			    else if (type == VRTTXT_TEXT)
			      {
				  txt_value = (char *) value;
				  is_txt = 1;
			      }
			}
		      goto eval;
		  }
		nCol++;
	    }
	  return 0;
	eval:
	  ok = 0;
	  if (pC->valueType == 'I')
	    {
		if (is_int)
		  {
		      switch (pC->op)
			{
			case SQLITE_INDEX_CONSTRAINT_EQ:
			    if (int_value == pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GT:
			    if (int_value > pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LE:
			    if (int_value <= pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LT:
			    if (int_value < pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GE:
			    if (int_value >= pC->intValue)
				ok = 1;
			    break;
			};
		  }
		if (is_dbl)
		  {
		      switch (pC->op)
			{
			case SQLITE_INDEX_CONSTRAINT_EQ:
			    if (dbl_value == pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GT:
			    if (dbl_value > pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LE:
			    if (dbl_value <= pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LT:
			    if (dbl_value < pC->intValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GE:
			    if (dbl_value >= pC->intValue)
				ok = 1;
			    break;
			};
		  }
	    }
	  if (pC->valueType == 'D')
	    {
		if (is_int)
		  {
		      switch (pC->op)
			{
			case SQLITE_INDEX_CONSTRAINT_EQ:
			    if (int_value == pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GT:
			    if (int_value > pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LE:
			    if (int_value <= pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LT:
			    if (int_value < pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GE:
			    if (int_value >= pC->dblValue)
				ok = 1;
			    break;
			};
		  }
		if (is_dbl)
		  {
		      switch (pC->op)
			{
			case SQLITE_INDEX_CONSTRAINT_EQ:
			    if (dbl_value == pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GT:
			    if (dbl_value > pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LE:
			    if (dbl_value <= pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LT:
			    if (dbl_value < pC->dblValue)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GE:
			    if (dbl_value >= pC->dblValue)
				ok = 1;
			    break;
			};
		  }
	    }
	  if (pC->valueType == 'T')
	    {
		if (is_txt)
		  {
		      int ret = strcmp (txt_value, pC->txtValue);
		      switch (pC->op)
			{
			case SQLITE_INDEX_CONSTRAINT_EQ:
			    if (ret == 0)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GT:
			    if (ret > 0)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LE:
			    if (ret <= 0)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_LT:
			    if (ret < 0)
				ok = 1;
			    break;
			case SQLITE_INDEX_CONSTRAINT_GE:
			    if (ret >= 0)
				ok = 1;
			    break;
			};
		  }
	    }
	  if (txt_value)
	    {
		free (txt_value);
		txt_value = NULL;
	    }
	  if (!ok)
	      return 0;
	  pC = pC->next;
      }
    if (txt_value)
	free (txt_value);
    return 1;
}
Example #3
0
static struct text_buffer *
text_parse (char *path, char *encoding, char first_line_titles,
	    char field_separator, char text_separator, char decimal_separator)
{
/* trying to open and parse the text file */
    int c;
    int fld;
    int len;
    int max_cell;
    int is_string = 0;
    char last = '\0';
    char *fields[4096];
    char buffer[35536];
    char *p = buffer;
    struct text_buffer *text;
    int nrows;
    int ncols;
    int errs;
    struct row_buffer *row;
    void *toUtf8;
    int encoding_errors;
    int ir;
    char title[64];
    char *first_valid_row;
    int i;
    char *name;
    for (fld = 0; fld < 4096; fld++)
      {
	  /* preparing an empty row */
	  fields[fld] = NULL;
      }
/* trying to open the text file */
    FILE *in = fopen (path, "rb");
    if (!in)
	return NULL;
    text = text_buffer_alloc ();
    fld = 0;
    while ((c = getc (in)) != EOF)
      {
	  /* parsing the file, one char at each time */
	  if (c == '\r' && !is_string)
	    {
		last = c;
		continue;
	    }
	  if (c == field_separator && !is_string)
	    {
		/* insering a field into the fields tmp array */
		last = c;
		*p = '\0';
		len = strlen (buffer);
		if (len)
		  {
		      fields[fld] = malloc (len + 1);
		      strcpy (fields[fld], buffer);
		  }
		fld++;
		p = buffer;
		*p = '\0';
		continue;
	    }
	  if (c == text_separator)
	    {
		/* found a text separator */
		if (is_string)
		  {
		      is_string = 0;
		      last = c;
		  }
		else
		  {
		      if (last == text_separator)
			  *p++ = text_separator;
		      is_string = 1;
		  }
		continue;
	    }
	  last = c;
	  if (c == '\n' && !is_string)
	    {
		/* inserting the row into the text buffer */
		*p = '\0';
		len = strlen (buffer);
		if (len)
		  {
		      fields[fld] = malloc (len + 1);
		      strcpy (fields[fld], buffer);
		  }
		fld++;
		p = buffer;
		*p = '\0';
		max_cell = -1;
		for (fld = 0; fld < 4096; fld++)
		  {
		      if (fields[fld])
			  max_cell = fld;
		  }
		text_insert_row (text, fields, max_cell);
		for (fld = 0; fld < 4096; fld++)
		  {
		      /* resetting an empty row */
		      fields[fld] = NULL;
		  }
		fld = 0;
		continue;
	    }
	  *p++ = c;
      }
    fclose (in);
/* checking if the text file really seems to contain a table */
    nrows = 0;
    ncols = 0;
    errs = 0;
    row = text->first;
    while (row)
      {
	  if (first_line_titles && row == text->first)
	    {
		/* skipping first line */
		row = row->next;
		continue;
	    }
	  nrows++;
	  if (row->n_cells > ncols)
	      ncols = row->n_cells;
	  row = row->next;
      }
    if (nrows == 0 && ncols == 0)
      {
	  text_buffer_free (text);
	  return NULL;
      }
    text->n_rows = nrows;
/* going to check the column types */
    text->max_n_cells = ncols;
    text->types = malloc (sizeof (char) * text->max_n_cells);
    first_valid_row = malloc (sizeof (char) * text->max_n_cells);
    for (fld = 0; fld < text->max_n_cells; fld++)
      {
	  /* initally assuming any cell contains TEXT */
	  *(text->types + fld) = VRTTXT_TEXT;
	  *(first_valid_row + fld) = 1;
      }
    row = text->first;
    while (row)
      {
	  if (first_line_titles && row == text->first)
	    {
		/* skipping first line */
		row = row->next;
		continue;
	    }
	  for (fld = 0; fld < row->n_cells; fld++)
	    {
		if (*(row->cells + fld))
		  {
		      if (text_is_integer (*(row->cells + fld)))
			{
			    if (*(first_valid_row + fld))
			      {
				  *(text->types + fld) = VRTTXT_INTEGER;
				  *(first_valid_row + fld) = 0;
			      }
			}
		      else if (text_is_double
			       (*(row->cells + fld), decimal_separator))
			{
			    if (*(first_valid_row + fld))
			      {
				  *(text->types + fld) = VRTTXT_DOUBLE;
				  *(first_valid_row + fld) = 0;
			      }
			    else
			      {
				  /* promoting an INTEGER column to be of the DOUBLE type */
				  if (*(text->types + fld) == VRTTXT_INTEGER)
				      *(text->types + fld) = VRTTXT_DOUBLE;
			      }
			}
		      else
			{
			    /* this column is anyway of the TEXT type */
			    *(text->types + fld) = VRTTXT_TEXT;
			    if (*(first_valid_row + fld))
				*(first_valid_row + fld) = 0;
			}
		  }
	    }
	  row = row->next;
      }
    free (first_valid_row);
/* preparing the column names */
    text->titles = malloc (sizeof (char *) * text->max_n_cells);
    if (first_line_titles)
      {
	  for (fld = 0; fld < text->max_n_cells; fld++)
	    {
		if (fld >= text->first->n_cells)
		  {
		      /* this column name is NULL; setting a default name */
		      sprintf (title, "COL%03d", fld + 1);
		      len = strlen (title);
		      *(text->titles + fld) = malloc (len + 1);
		      strcpy (*(text->titles + fld), title);
		  }
		else
		  {
		      if (*(text->first->cells + fld))
			{
			    len = strlen (*(text->first->cells + fld));
			    *(text->titles + fld) = malloc (len + 1);
			    strcpy (*(text->titles + fld),
				    *(text->first->cells + fld));
			    name = *(text->titles + fld);
			    for (i = 0; i < len; i++)
			      {
				  /* masking any space in the column name */
				  if (*(name + i) == ' ')
				      *(name + i) = '_';
			      }
			}
		      else
			{
			    /* this column name is NULL; setting a default name */
			    sprintf (title, "COL%03d", fld + 1);
			    len = strlen (title);
			    *(text->titles + fld) = malloc (len + 1);
			    strcpy (*(text->titles + fld), title);
			}
		  }
	    }
      }
    else
      {
	  for (fld = 0; fld < text->max_n_cells; fld++)
	    {
		sprintf (title, "COL%03d", fld + 1);
		len = strlen (title);
		*(text->titles + fld) = malloc (len + 1);
		strcpy (*(text->titles + fld), title);
	    }
      }
/* cleaning cell values when needed */
    toUtf8 = iconvCreateUTF8Converter (encoding);
    if (!toUtf8)
      {
	  text_buffer_free (text);
	  return NULL;
      }
    encoding_errors = 0;
    row = text->first;
    while (row)
      {
	  if (first_line_titles && row == text->first)
	    {
		/* skipping first line */
		row = row->next;
		continue;
	    }
	  for (fld = 0; fld < row->n_cells; fld++)
	    {
		if (*(row->cells + fld))
		  {
		      if (*(text->types + fld) == VRTTXT_INTEGER)
			  text_clean_integer (*(row->cells + fld));
		      else if (*(text->types + fld) == VRTTXT_DOUBLE)
			  text_clean_double (*(row->cells + fld));
		      else
			  encoding_errors +=
			      text_clean_text (row->cells + fld, toUtf8);
		  }
	    }
	  row = row->next;
      }
    iconvFreeUTF8Converter (toUtf8);
    if (encoding_errors)
      {
	  text_buffer_free (text);
	  return NULL;
      }
/* ok, we can now go to prepare the rows array */
    text->rows = malloc (sizeof (struct text_row *) * text->n_rows);
    ir = 0;
    row = text->first;
    while (row)
      {
	  if (first_line_titles && row == text->first)
	    {
		/* skipping first line */
		row = row->next;
		continue;
	    }
	  *(text->rows + ir++) = row;
	  row = row->next;
      }
    return text;
}