示例#1
0
文件: ls_sqlite3.c 项目: 0w/moai-dev
/*
** Get another row of the given cursor.
*/
static int cur_fetch (lua_State *L) {
  cur_data *cur = getcursor(L);
  sqlite3_stmt *vm = cur->sql_vm;
  int res;

  if (vm == NULL)
    return 0;

  res = sqlite3_step(vm);

  /* no more results? */
  if (res == SQLITE_DONE)
    return finalize(L, cur);

  if (res != SQLITE_ROW)
    return finalize(L, cur);

  if (lua_istable (L, 2))
    {
      int i;
      const char *opts = luaL_optstring(L, 3, "n");

      if (strchr(opts, 'n') != NULL)
        {
	  /* Copy values to numerical indices */
	  for (i = 0; i < cur->numcols;)
            {
	      push_column(L, vm, i);
	      lua_rawseti(L, 2, ++i);
	    }
        }
      if (strchr(opts, 'a') != NULL)
        {
	  /* Copy values to alphanumerical indices */
	  lua_rawgeti(L, LUA_REGISTRYINDEX, cur->colnames);

	  for (i = 0; i < cur->numcols; i++)
            {
	      lua_rawgeti(L, -1, i+1);
	      push_column(L, vm, i);
	      lua_rawset (L, 2);
	    }
        }
      lua_pushvalue(L, 2);
      return 1; /* return table */
    }
  else
    {
      int i;
      luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns");
      for (i = 0; i < cur->numcols; ++i)
	push_column(L, vm, i);
      return cur->numcols; /* return #numcols values */
    }
}
示例#2
0
/*
 * mode: 0 = direct, 1 = integer, 2 = alphanumeric
 */
static int l_sqlite3_row_mode(lua_State * L, int mode)
{
  /* Old code / Just a reminder / To be removed: 
  ** checkargs(L, 1, 2, CHECK_PTR, CHECK_NILTABLE, 0);
  */
  
  sqlite3_stmt * stmt	= checkstmt_stmt(L, 1);
  int num_columns	= sqlite3_data_count(stmt);	/* Maybe wrong state, so don't use sqlite3_column_count */
  int index;
  
  /* XXX Should really be cleaned up... Fixme! */
  
  if (mode == 0)
    lua_checkstack(L, num_columns);
  else
    if (!lua_istable(L, -1))
      lua_newtable(L);
  
  for (index=0; index<num_columns; index++)
    switch(mode)
    {
      case 0:	/* direct mode */
        push_column(L, stmt, index);
        break;
      
      case 1:	/* integer mode */
        push_column(L, stmt, index);
        lua_rawseti(L, -2, index+1);
        break;
      
      case 2:	/* alphanumeric mode */
        lua_pushstring(L, sqlite3_column_name(stmt, index));
        push_column(L, stmt, index);
        lua_rawset(L, -3);
        break;
      
      default:
        report_error(L, "libluasqlite3: Internal error in sqlite3_row_mode");
    }
  
  if (mode)
    return 1;
  else
    return num_columns;
}
示例#3
0
/*
** Get another row of the given cursor.
*/
static int cur_fetch (lua_State *L) {
    cur_data *cur = (cur_data *) getcursor (L);
    SQLHSTMT hstmt = cur->hstmt;
    int ret; 
    SQLRETURN rc = SQLFetch(cur->hstmt); 
    if (rc == SQL_NO_DATA) {
        lua_pushnil(L);
        return 1;
    } else if (error(rc)) return fail(L, hSTMT, hstmt);

	if (lua_istable (L, 2)) {
		SQLUSMALLINT i;
		const char *opts = luaL_optstring (L, 3, "n");
		int num = strchr (opts, 'n') != NULL;
		int alpha = strchr (opts, 'a') != NULL;
		for (i = 1; i <= cur->numcols; i++) {
			ret = push_column (L, cur->coltypes, hstmt, i);
			if (ret)
				return ret;
			if (alpha) {
				lua_rawgeti (L, LUA_REGISTRYINDEX, cur->colnames);
				lua_rawgeti (L, -1, i); /* gets column name */
				lua_pushvalue (L, -3); /* duplicates column value */
				lua_rawset (L, 2); /* table[name] = value */
				lua_pop (L, 1);	/* pops colnames table */
			}
			if (num)
				lua_rawseti (L, 2, i);
			else
				lua_pop (L, 1); /* pops value */
		}
		lua_pushvalue (L, 2);
		return 1;	/* return table */
	}
	else {
		SQLUSMALLINT i;
		luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns");
		for (i = 1; i <= cur->numcols; i++) {
			ret = push_column (L, cur->coltypes, hstmt, i);
			if (ret)
				return ret;
		}
		return cur->numcols;
	}
}
示例#4
0
/*
** Returns a row of data from the query
** Lua Returns:
**   list of results or table of results depending on call
**   nil and error message otherwise.
*/
static int cur_fetch (lua_State *L) {
    ISC_STATUS fetch_stat;
    int i;
    cur_data *cur = getcursor(L,1);
    const char *opts = luaL_optstring (L, 3, "n");
    int num = strchr(opts, 'n') != NULL;
    int alpha = strchr(opts, 'a') != NULL;

    if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) {
        if (lua_istable (L, 2)) {
            /* remove the option string */
            lua_settop(L, 2);

            /* loop through the columns */
            for (i = 0; i < cur->out_sqlda->sqld; i++) {
                push_column(L, i, cur);

                if( num ) {
                    lua_pushnumber(L, i+1);
                    lua_pushvalue(L, -2);
                    lua_settable(L, 2);
                }

                if( alpha ) {
                    lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length);
                    lua_pushvalue(L, -2);
                    lua_settable(L, 2);
                }

                lua_pop(L, 1);
            }

            /* returning given table */
            return 1;
        } else {
            for (i = 0; i < cur->out_sqlda->sqld; i++)
                push_column(L, i, cur);

            /* returning a list of values */
            return cur->out_sqlda->sqld;
        }
    }

    /* isc_dsql_fetch returns 100 if no more rows remain to be retrieved
       so this can be ignored */
    if (fetch_stat != 100L)
        return return_db_error(L, cur->env->status_vector);

    /* last row has been fetched, close cursor */
    isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop);
    if ( CHECK_DB_ERROR(cur->env->status_vector) )
        return return_db_error(L, cur->env->status_vector);

    /* free the cursor data */
    free_cur(cur);

    cur->closed = 1;

    /* remove cursor from lock count */
    --cur->conn->lock;

    /* return sucsess */
    return 0;
}
示例#5
0
void test_scored_subexpression() {
  // Create a database with the default options.
  auto db = grnxx::open_db("");

  // Create a table with the default options.
  auto table = db->create_table("Table");

  constexpr size_t NUM_ROWS = 1 << 16;

  // Generate random values.
  grnxx::Array<grnxx::Float> float_values;
  grnxx::Array<grnxx::Int> ref_values;
  float_values.resize(NUM_ROWS);
  ref_values.resize(NUM_ROWS);
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    float_values[i] = grnxx::Float(1.0 * rng() / rng.max());
//    ref_values[i] = mersenne_twister() % NUM_ROWS;
    ref_values[i] = grnxx::Int(0);
  }

  // Create columns for Float and Int values.
  auto float_column = table->create_column("Float", GRNXX_FLOAT);
  grnxx::ColumnOptions options;
  options.reference_table_name = "Table";
  auto ref_column = table->create_column("Ref", GRNXX_INT, options);

  // Store generated values into columns.
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    grnxx::Int row_id = table->insert_row();
    assert(row_id.match(grnxx::Int(i)));
    float_column->set(row_id, float_values[i]);
  }
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    ref_column->set(grnxx::Int(i), ref_values[i]);
  }

  // Generate a list of records.
  grnxx::Array<grnxx::Record> records;
  auto cursor = table->create_cursor();
  assert(cursor->read_all(&records) == table->num_rows());

  // Set scores (Float).
  auto builder = grnxx::ExpressionBuilder::create(table);
  builder->push_column("Float");
  auto expression = builder->release();
  expression->adjust(&records);

  // Test an expression (Ref.(_score > 0.5)).
  builder->push_column("Ref");
  builder->begin_subexpression();
  builder->push_score();
  builder->push_constant(grnxx::Float(0.5));
  builder->push_operator(GRNXX_GREATER);
  builder->end_subexpression();
  expression = builder->release();

  expression->filter(&records);
  size_t count = 0;
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    if (float_values[i].raw() > 0.5) {
      assert(records[count].row_id.match(grnxx::Int(i)));
      ++count;
    }
  }
  assert(records.size() == count);
}