예제 #1
0
static int
statement_fetch_impl_start (lua_State * L, statement_t * statement) /* {{{ */
{
  int column_count;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

  if (!statement->stmt)
    {
      luaL_error (L, DBI_ERR_FETCH_INVALID);
      return 0;
    }

  if (!statement->metadata)
    {
      luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE);
      return 0;
    }

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;

      real_length = calloc (column_count, sizeof (unsigned long));

      statement->bind = malloc (sizeof (MYSQL_BIND) * column_count);
      memset (statement->bind, 0, sizeof (MYSQL_BIND) * column_count);

      statement->fields = mysql_fetch_fields (statement->metadata);

      for (i = 0; i < column_count; i++)
	{
	  unsigned int length = mysql_buffer_size (&statement->fields[i]);
	  if (length > sizeof (MYSQL_TIME))
	    {
	      statement->bind[i].buffer = NULL;
	      statement->bind[i].buffer_length = 0;
	    }
	  else
	    {
	      char *buffer = (char *) malloc (length);
	      memset (buffer, 0, length);

	      statement->bind[i].buffer = buffer;
	      statement->bind[i].buffer_length = length;
	    }

	  statement->bind[i].buffer_type = statement->fields[i].type;
	  statement->bind[i].length = &real_length[i];
	}

      if (mysql_stmt_bind_result (statement->stmt, statement->bind))
	{
	  error_message = DBI_ERR_BINDING_RESULTS;
	  goto cleanup;
	}

      statement->event =
	mysql_stmt_fetch_start (&(statement->ret), statement->stmt);

      if (statement->event & MYSQL_WAIT_EXCEPT)
	{
	  lua_pushnil (L);
	  return 1;
	}
      if (statement->event & MYSQL_WAIT_TIMEOUT)
	{
	  statement->timeout =
	    1000 * mysql_get_timeout_value_ms (statement->mysql);
	}

      lua_pushboolean (L, 1);
      lua_pushnumber (L, statement->event);
      return 2;
    }
  else
    {
      lua_pushnil (L);
      return 1;
    }


cleanup:
  free (real_length);

  if (statement->bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (statement->bind[i].buffer);
	}

      free (statement->bind);
    }


  if (error_message)
    {
      luaL_error (L, error_message, mysql_stmt_error (statement->stmt));
      return 0;
    }

  return 1;
} /* }}} */
예제 #2
0
static int
statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */
		      int named_columns)
{
  int column_count, fetch_result_ok;
  MYSQL_BIND *bind = NULL;
  unsigned long *real_length = NULL;
  const char *error_message = NULL;

  if (!statement->stmt)
    {
      luaL_error (L, DBI_ERR_FETCH_INVALID);
      return 0;
    }

  if (!statement->metadata)
    {
      luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE);
      return 0;
    }

  column_count = mysql_num_fields (statement->metadata);

  if (column_count > 0)
    {
      int i;
      MYSQL_FIELD *fields;

      real_length = calloc (column_count, sizeof (unsigned long));

      bind = malloc (sizeof (MYSQL_BIND) * column_count);
      memset (bind, 0, sizeof (MYSQL_BIND) * column_count);

      fields = mysql_fetch_fields (statement->metadata);

      for (i = 0; i < column_count; i++)
	{
	  unsigned int length = mysql_buffer_size (&fields[i]);
	  if (length > sizeof (MYSQL_TIME))
	    {
	      bind[i].buffer = NULL;
	      bind[i].buffer_length = 0;
	    }
	  else
	    {
	      char *buffer = (char *) malloc (length);
	      memset (buffer, 0, length);

	      bind[i].buffer = buffer;
	      bind[i].buffer_length = length;
	    }

	  bind[i].buffer_type = fields[i].type;
	  bind[i].length = &real_length[i];
	}

      if (mysql_stmt_bind_result (statement->stmt, bind))
	{
	  error_message = DBI_ERR_BINDING_RESULTS;
	  goto cleanup;
	}

      fetch_result_ok = mysql_stmt_fetch (statement->stmt);
      if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED)
	{
	  int d = 1;

	  lua_newtable (L);
	  for (i = 0; i < column_count; i++)
	    {
	      lua_push_type_t lua_push = mysql_to_lua_push (fields[i].type);
	      const char *name = fields[i].name;

	      if (bind[i].buffer == NULL)
		{
		  char *buffer =
		    (char *) calloc (real_length[i] + 1, sizeof (char));
		  bind[i].buffer = buffer;
		  bind[i].buffer_length = real_length[i];
		  mysql_stmt_fetch_column (statement->stmt, &bind[i], i, 0);
		}

	      if (lua_push == LUA_PUSH_NIL)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_NIL (name);
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_NIL (d);
		    }
		}
	      else if (lua_push == LUA_PUSH_INTEGER)
		{
		  if (fields[i].type == MYSQL_TYPE_YEAR
		      || fields[i].type == MYSQL_TYPE_SHORT)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(short *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(short *) (bind[i].buffer));
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TINY)
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       (int) *(char
						       *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d,
					      (int) *(char
						      *) (bind[i].buffer));
			}
		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_INT (name,
					       *(int *) (bind[i].buffer));
			}
		      else
			{
			  LUA_PUSH_ARRAY_INT (d, *(int *) (bind[i].buffer));
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_NUMBER)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_FLOAT (name,
					     *(double *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_FLOAT (d, *(double *) (bind[i].buffer));
		    }
		}
	      else if (lua_push == LUA_PUSH_STRING)
		{

		  if (fields[i].type == MYSQL_TYPE_TIMESTAMP
		      || fields[i].type == MYSQL_TYPE_DATETIME)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d",
				t->year, t->month, t->day, t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_TIME)
		    {
		      char str[9];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 9, "%02d:%02d:%02d", t->hour,
				t->minute, t->second);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}
		    }
		  else if (fields[i].type == MYSQL_TYPE_DATE)
		    {
		      char str[20];
		      struct st_mysql_time *t = bind[i].buffer;

		      snprintf (str, 11, "%d-%02d-%02d", t->year,
				t->month, t->day);

		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, str);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, str);
			}

		    }
		  else
		    {
		      if (named_columns)
			{
			  LUA_PUSH_ATTRIB_STRING (name, bind[i].buffer);
			}
		      else
			{
			  LUA_PUSH_ARRAY_STRING (d, bind[i].buffer);
			}
		    }
		}
	      else if (lua_push == LUA_PUSH_BOOLEAN)
		{
		  if (named_columns)
		    {
		      LUA_PUSH_ATTRIB_BOOL (name, *(int *) (bind[i].buffer));
		    }
		  else
		    {
		      LUA_PUSH_ARRAY_BOOL (d, *(int *) (bind[i].buffer));
		    }
		}
	      else
		{
		  luaL_error (L, DBI_ERR_UNKNOWN_PUSH);
		}
	    }
	}
      else
	{
	  lua_pushnil (L);
	}
    }

cleanup:
  free (real_length);

  if (bind)
    {
      int i;

      for (i = 0; i < column_count; i++)
	{
	  free (bind[i].buffer);
	}

      free (bind);
    }

  if (error_message)
    {
      luaL_error (L, error_message, mysql_stmt_error (statement->stmt));
      return 0;
    }

  return 1;
} /* }}} */
예제 #3
0
파일: statement.c 프로젝트: nikkiii/luadbi
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
    int column_count;
    MYSQL_BIND *bind = NULL;
    const char *error_message = NULL;

    if (!statement->stmt) {
		luaL_error(L, DBI_ERR_FETCH_INVALID);
		return 0;
    }

    if (!statement->metadata) {
		luaL_error(L, DBI_ERR_FETCH_NO_EXECUTE);
		return 0;
    }

    column_count = mysql_num_fields(statement->metadata);

    if (column_count > 0) {
		int i;
		MYSQL_FIELD *fields;

        bind = malloc(sizeof(MYSQL_BIND) * column_count);
        memset(bind, 0, sizeof(MYSQL_BIND) * column_count);

		fields = mysql_fetch_fields(statement->metadata);

		for (i = 0; i < column_count; i++) {
			unsigned int length = mysql_buffer_size(&fields[i]);
			char *buffer = (char *) malloc(length);
			memset(buffer, 0, length);

			bind[i].buffer_type = fields[i].type; 
			bind[i].buffer = buffer;
			bind[i].buffer_length = length;
		}

		if (mysql_stmt_bind_result(statement->stmt, bind)) {
			error_message = DBI_ERR_BINDING_RESULTS;
			goto cleanup;
		}

		if (!mysql_stmt_fetch(statement->stmt)) {
			int d = 1;

			lua_newtable(L);
			for (i = 0; i < column_count; i++) {
				lua_push_type_t lua_push = mysql_to_lua_push(fields[i].type);
				const char *name = fields[i].name;

				if (lua_push == LUA_PUSH_NIL) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_NIL(name);
					} else {
						LUA_PUSH_ARRAY_NIL(d);
					}
				} else if (lua_push == LUA_PUSH_INTEGER) {
					if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, *(short *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, *(short *)(bind[i].buffer)); 
						}
					} else if (fields[i].type == MYSQL_TYPE_TINY) {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, (int)*(char *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, (int)*(char *)(bind[i].buffer)); 
						}
					} else {
						if (named_columns) {
							LUA_PUSH_ATTRIB_INT(name, *(int *)(bind[i].buffer)); 
						} else {
							LUA_PUSH_ARRAY_INT(d, *(int *)(bind[i].buffer)); 
						}
					}
				} else if (lua_push == LUA_PUSH_NUMBER) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer));
					} else {
						LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer));
					}
				} else if (lua_push == LUA_PUSH_STRING) {
					if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) {
						char str[20];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
					} else if (fields[i].type == MYSQL_TYPE_TIME) {
						char str[9];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
						} else if (fields[i].type == MYSQL_TYPE_DATE) {
						char str[20];
						struct st_mysql_time *t = bind[i].buffer;

						snprintf(str, 11, "%d-%02d-%02d", t->year, t->month, t->day);

						if (named_columns) {
							LUA_PUSH_ATTRIB_STRING(name, str);
						} else {
							LUA_PUSH_ARRAY_STRING(d, str);
						}
					} else {
						size_t length = bind[i].buffer_length;
						//
						//  hack for strings. have no idea what 8 means but it is different from value for binary blobs, which is good enough
						//
						if (fields[i].charsetnr == 8) {
							length = min(bind[i].buffer_length, strlen(bind[i].buffer));
						}
						if (named_columns) {
							LUA_PUSH_ATTRIB_LSTRING(name, bind[i].buffer, length);
						} else {
							LUA_PUSH_ARRAY_LSTRING(d, bind[i].buffer, length);
						}
					}
				} else if (lua_push == LUA_PUSH_BOOLEAN) {
					if (named_columns) {
						LUA_PUSH_ATTRIB_BOOL(name, *(int *)(bind[i].buffer));
					} else {
						LUA_PUSH_ARRAY_BOOL(d, *(int *)(bind[i].buffer));
					}
				} else {
					luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
				}
			}
		} else {
			lua_pushnil(L);	    
		}
    }

cleanup:
    if (bind) {
	int i;

	for (i = 0; i < column_count; i++) {
	    free(bind[i].buffer);
	}

	free(bind);
    }

    if (error_message) {
        luaL_error(L, error_message, mysql_stmt_error(statement->stmt));
        return 0;
    }

    return 1;    
}