lua_connector.c 6.8 KB
Newer Older
1
#include <stdio.h>
2 3 4
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
5 6 7 8
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "taos.h"
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

struct cb_param{
  lua_State* state;
  int callback;
  void * stream;
};

struct async_query_callback_param{
  lua_State* state;
  int callback;
};

static int l_connect(lua_State *L){
  TAOS *    taos=NULL;
  const char* host;
  const char* database;
  const char* user;
  const char* password;
  int port;

  luaL_checktype(L, 1, LUA_TTABLE);

31
  lua_getfield(L, 1,"host");
32 33 34 35 36 37
  if (lua_isstring(L,-1)){
    host = lua_tostring(L, -1);
    // printf("host = %s\n", host);
  }
  
  lua_getfield(L, 1, "port");
38
  if (lua_isinteger(L, -1)){
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    port = lua_tointeger(L, -1);
    //printf("port = %d\n", port);
  }
  
  lua_getfield(L, 1, "database");
  if (lua_isstring(L, -1)){
    database = lua_tostring(L, -1);
    //printf("database = %s\n", database);
  }
  
  lua_getfield(L, 1, "user");
  if (lua_isstring(L, -1)){
    user = lua_tostring(L, -1);
    //printf("user = %s\n", user);
  }

  lua_getfield(L, 1, "password");
  if (lua_isstring(L, -1)){
    password = lua_tostring(L, -1);
    //printf("password = %s\n", password);
  }

  lua_settop(L,0);

  lua_newtable(L);
  int table_index = lua_gettop(L);

  taos = taos_connect(host, user,password,database, port);
  if (taos == NULL) {
    printf("failed to connect server, reason:%s\n", taos_errstr(taos));
    
    lua_pushinteger(L, -1);
    lua_setfield(L, table_index, "code");
    lua_pushstring(L, taos_errstr(taos));
    lua_setfield(L, table_index, "error");    
    lua_pushlightuserdata(L,NULL);
    lua_setfield(L, table_index, "conn");
  }else{
    // printf("success to connect server\n");
    lua_pushinteger(L, 0);
    lua_setfield(L, table_index, "code");
    lua_pushstring(L, taos_errstr(taos));
    lua_setfield(L, table_index, "error");    
    lua_pushlightuserdata(L,taos);
    lua_setfield(L, table_index, "conn");
  }
  
  return 1;
}

static int l_query(lua_State *L){
  TAOS *taos= (TAOS*)lua_topointer(L,1);
  const char* s = lua_tostring(L, 2);
  TAOS_RES *result;
  lua_newtable(L);
  int table_index = lua_gettop(L);

  //  printf("receive command:%s\r\n",s);
  result = taos_query(taos, s);
  int32_t code = taos_errno(result);
  if( code != 0){
    printf("failed, reason:%s\n", taos_errstr(result));
    lua_pushinteger(L, -1);
    lua_setfield(L, table_index, "code");    
103
    lua_pushstring(L, taos_errstr(result));
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
    lua_setfield(L, table_index, "error");    
   
    return 1;
    
  }else{
    //printf("success to query.\n");
    TAOS_ROW    row;
    int         rows = 0;
    int         num_fields = taos_field_count(result);
    const TAOS_FIELD *fields = taos_fetch_fields(result);

    const int affectRows = taos_affected_rows(result);
    //    printf(" affect rows:%d\r\n", affectRows);
    lua_pushinteger(L, 0);
    lua_setfield(L, table_index, "code");
    lua_pushinteger(L, affectRows);
    lua_setfield(L, table_index, "affected");
    lua_newtable(L);
122

123 124 125 126 127 128 129 130 131 132 133 134 135
    while ((row = taos_fetch_row(result))) {
      //printf("row index:%d\n",rows);
      rows++;

      lua_pushnumber(L,rows);
      lua_newtable(L);

      for (int i = 0; i < num_fields; ++i) {
	if (row[i] == NULL) {
	  continue;
	}

	lua_pushstring(L,fields[i].name);
136
	int32_t* length = taos_fetch_lengths(result);
137
	switch (fields[i].type) {
138
	case TSDB_DATA_TYPE_UTINYINT:
139 140 141
	case TSDB_DATA_TYPE_TINYINT:
	  lua_pushinteger(L,*((char *)row[i]));
	  break;
142
	case TSDB_DATA_TYPE_USMALLINT:
143 144 145
	case TSDB_DATA_TYPE_SMALLINT:
	  lua_pushinteger(L,*((short *)row[i]));
	  break;
146
	case TSDB_DATA_TYPE_UINT:
147 148 149
	case TSDB_DATA_TYPE_INT:
	  lua_pushinteger(L,*((int *)row[i]));
	  break;
150
	case TSDB_DATA_TYPE_UBIGINT:
151 152 153 154 155 156 157 158 159
	case TSDB_DATA_TYPE_BIGINT:
	  lua_pushinteger(L,*((int64_t *)row[i]));
	  break;
	case TSDB_DATA_TYPE_FLOAT:
	  lua_pushnumber(L,*((float *)row[i]));
	  break;
	case TSDB_DATA_TYPE_DOUBLE:
	  lua_pushnumber(L,*((double *)row[i]));
	  break;
160
	case TSDB_DATA_TYPE_JSON:
161 162
	case TSDB_DATA_TYPE_BINARY:
	case TSDB_DATA_TYPE_NCHAR:
163 164
	  //printf("type:%d, max len:%d, current len:%d\n",fields[i].type, fields[i].bytes, length[i]);
	  lua_pushlstring(L,(char *)row[i], length[i]);
165 166 167 168 169 170 171
	  break;
	case TSDB_DATA_TYPE_TIMESTAMP:
	  lua_pushinteger(L,*((int64_t *)row[i]));
	  break;
	case TSDB_DATA_TYPE_BOOL:
	  lua_pushinteger(L,*((char *)row[i]));
	  break;
172
	case TSDB_DATA_TYPE_NULL:
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
	default:
	  lua_pushnil(L);
	  break;
	}

	lua_settable(L,-3);
      }

      lua_settable(L,-3);
    }
    taos_free_result(result);    
  }

  lua_setfield(L, table_index, "item");
  return 1;
}

void async_query_callback(void *param, TAOS_RES *result, int code){
  struct async_query_callback_param* p = (struct async_query_callback_param*) param;

  //printf("\nin c,numfields:%d\n", numFields);
  //printf("\nin c, code:%d\n", code);

  lua_State *L = p->state;
  lua_rawgeti(L, LUA_REGISTRYINDEX, p->callback);
  lua_newtable(L);
  int table_index = lua_gettop(L);
  if( code < 0){
    printf("failed, reason:%s\n", taos_errstr(result));
    lua_pushinteger(L, -1);
    lua_setfield(L, table_index, "code");    
    lua_pushstring(L,"something is wrong");// taos_errstr(taos));
    lua_setfield(L, table_index, "error");    
  }else{
    //printf("success to async query.\n");
    const int affectRows = taos_affected_rows(result);
    //printf(" affect rows:%d\r\n", affectRows);
    lua_pushinteger(L, 0);
    lua_setfield(L, table_index, "code");
    lua_pushinteger(L, affectRows);
    lua_setfield(L, table_index, "affected");
  }
  
  lua_call(L, 1, 0);
}

static int l_async_query(lua_State *L){
  int r = luaL_ref(L, LUA_REGISTRYINDEX);
  TAOS *    taos = (TAOS*)lua_topointer(L,1);
  const char * sqlstr = lua_tostring(L,2);
  // int stime = luaL_checknumber(L,3);

  lua_newtable(L);
  int table_index = lua_gettop(L);

  struct async_query_callback_param *p = malloc(sizeof(struct async_query_callback_param));
  p->state = L;
  p->callback=r;
  // printf("r:%d, L:%d\n",r,L);
  taos_query_a(taos,sqlstr,async_query_callback,p);

  lua_pushnumber(L, 0);
  lua_setfield(L, table_index, "code");
  lua_pushstring(L, "ok");
  lua_setfield(L, table_index, "error");
  
  return 1;
}


static int l_close(lua_State *L){
  TAOS *taos= (TAOS*)lua_topointer(L,1);
  lua_newtable(L);
  int table_index = lua_gettop(L);
  
  if(taos == NULL){
    lua_pushnumber(L, -1);
    lua_setfield(L, table_index, "code");    
    lua_pushstring(L, "null pointer.");
    lua_setfield(L, table_index, "error"); 
  }else{
    taos_close(taos);
    lua_pushnumber(L, 0);
    lua_setfield(L, table_index, "code");    
    lua_pushstring(L, "done.");
    lua_setfield(L, table_index, "error");    
  }
  return 1;
}

static const struct luaL_Reg lib[] = {
    {"connect", l_connect},
    {"query", l_query},
    {"query_a",l_async_query},
    {"close", l_close},
    {NULL, NULL}
};

extern int luaopen_luaconnector(lua_State* L)
{
    luaL_newlib(L, lib);

    return 1;
}