luat_lib_fdb.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. @module fdb
  3. @summary kv数据库(基于FlashDB)
  4. @version 1.0
  5. @date 2021.11.03
  6. @demo fdb
  7. */
  8. #include "luat_base.h"
  9. #include "luat_msgbus.h"
  10. #include "flashdb.h"
  11. static struct fdb_kvdb kvdb;
  12. /**
  13. 初始化kv数据库
  14. @api fdb.kvdb_init(name, partition)
  15. @string 数据库名,当前仅支持env
  16. @string FAL分区名,当前仅支持onchip_fdb
  17. @return boolean 成功返回true,否则返回false
  18. @usage
  19. if fdb.kvdb_init("env", "onchip_fdb") then
  20. log.info("fdb", "kv数据库初始化成功")
  21. end
  22. */
  23. static int l_fdb_kvdb_init(lua_State *L) {
  24. fdb_err_t ret = fdb_kvdb_init(&kvdb, "env", "onchip_fdb", NULL, NULL);
  25. if (ret) {
  26. LLOGD("fdb_kvdb_init ret=%d", ret);
  27. }
  28. lua_pushboolean(L, ret == 0 ? 1 : 0);
  29. return 1;
  30. }
  31. // 暂时对外公开
  32. static int l_fdb_kvdb_deinit(lua_State *L) {
  33. fdb_err_t ret = fdb_kvdb_deinit(&kvdb);
  34. if (ret) {
  35. LLOGD("fdb_kvdb_deinit ret=%d", ret);
  36. }
  37. lua_pushboolean(L, ret == FDB_NO_ERR ? 1 : 0);
  38. return 1;
  39. }
  40. /**
  41. 设置一对kv数据
  42. @api fdb.kv_set(key, value)
  43. @string key的名称,必填,不能空字符串
  44. @string 用户数据,必填,不能nil, 支持字符串/数值/table/布尔值
  45. @return boolean 成功返回true,否则返回false
  46. @usage
  47. if fdb.kvdb_init("env", "onchip_fdb") then
  48. log.info("fdb", fdb.kv_set("wendal", "goodgoodstudy"))
  49. end
  50. */
  51. static int l_fdb_kv_set(lua_State *L) {
  52. size_t len;
  53. struct fdb_blob blob = {0};
  54. luaL_Buffer buff;
  55. luaL_buffinit(L, &buff);
  56. const char* key = luaL_checkstring(L, 1);
  57. //luaL_addchar(&buff, 0xA5);
  58. int type = lua_type(L, 2);
  59. switch (type)
  60. {
  61. case LUA_TBOOLEAN:
  62. luaL_addchar(&buff, LUA_TBOOLEAN);
  63. bool val = lua_toboolean(L, 2);
  64. luaL_addlstring(&buff, (const char*)&val, sizeof(val));
  65. break;
  66. case LUA_TNUMBER:
  67. if (lua_isinteger(L, 2)) {
  68. luaL_addchar(&buff, LUA_TINTEGER); // 自定义类型
  69. lua_Integer val = luaL_checkinteger(L, 2);
  70. luaL_addlstring(&buff, (const char*)&val, sizeof(val));
  71. }
  72. else {
  73. luaL_addchar(&buff, LUA_TNUMBER);
  74. lua_getglobal(L, "pack");
  75. if (lua_isnil(L, -1)) {
  76. LLOGW("float number need pack lib");
  77. lua_pushboolean(L, 0);
  78. return 1;
  79. }
  80. lua_getfield(L, -1, "pack");
  81. lua_pushstring(L, ">f");
  82. lua_pushvalue(L, 2);
  83. lua_call(L, 2, 1);
  84. if (lua_isstring(L, -1)) {
  85. const char* val = luaL_checklstring(L, -1, &len);
  86. luaL_addlstring(&buff, val, len);
  87. }
  88. else {
  89. LLOGW("kdb store number fail!!");
  90. lua_pushboolean(L, 0);
  91. return 1;
  92. }
  93. }
  94. break;
  95. case LUA_TSTRING:
  96. {
  97. luaL_addchar(&buff, LUA_TSTRING);
  98. const char* val = luaL_checklstring(L, 2, &len);
  99. luaL_addlstring(&buff, val, len);
  100. break;
  101. }
  102. case LUA_TTABLE:
  103. {
  104. lua_settop(L, 2);
  105. lua_getglobal(L, "json");
  106. if (lua_isnil(L, -1)) {
  107. LLOGW("miss json lib, not support table value");
  108. lua_pushboolean(L, 0);
  109. return 1;
  110. }
  111. lua_getfield(L, -1, "encode");
  112. if (lua_isfunction(L, -1)) {
  113. lua_pushvalue(L, 2);
  114. lua_call(L, 1, 1);
  115. if (lua_isstring(L, -1)) {
  116. luaL_addchar(&buff, LUA_TTABLE);
  117. const char* val = luaL_checklstring(L, -1, &len);
  118. luaL_addlstring(&buff, val, len);
  119. }
  120. else {
  121. LLOGW("json.encode(val) report error");
  122. lua_pushboolean(L, 0);
  123. return 1;
  124. }
  125. }
  126. else {
  127. LLOGW("miss json.encode, not support table value");
  128. lua_pushboolean(L, 0);
  129. return 1;
  130. }
  131. break;
  132. }
  133. default:
  134. {
  135. LLOGW("function/userdata/nil/thread isn't allow");
  136. lua_pushboolean(L, 0);
  137. return 1;
  138. }
  139. }
  140. blob.buf = buff.b;
  141. blob.size = buff.n;
  142. fdb_err_t ret = fdb_kv_set_blob(&kvdb, key, &blob);
  143. lua_pushboolean(L, ret == FDB_NO_ERR ? 1 : 0);
  144. lua_pushinteger(L, ret);
  145. return 2;
  146. }
  147. /**
  148. 根据key获取对应的数据
  149. @api fdb.kv_get(key)
  150. @string key的名称,必填,不能空字符串
  151. @return any 存在则返回数据,否则返回nil
  152. @usage
  153. if fdb.kvdb_init("env", "onchip_fdb") then
  154. log.info("fdb", fdb.kv_get("wendal"))
  155. end
  156. */
  157. static int l_fdb_kv_get(lua_State *L) {
  158. // size_t len;
  159. luaL_Buffer buff;
  160. struct fdb_blob blob = {0};
  161. const char* key = luaL_checkstring(L, 1);
  162. luaL_buffinit(L, &buff);
  163. blob.buf = buff.b;
  164. blob.size = buff.size;
  165. size_t read_len = fdb_kv_get_blob(&kvdb, key, &blob);
  166. lua_Integer *intVal;
  167. // lua_Number *numVal;
  168. if (read_len) {
  169. // LLOGD("KV value T=%02X", buff.b[0]);
  170. switch(buff.b[0]) {
  171. case LUA_TBOOLEAN:
  172. lua_pushboolean(L, buff.b[1]);
  173. break;
  174. case LUA_TNUMBER:
  175. lua_getglobal(L, "pack");
  176. lua_getfield(L, -1, "unpack");
  177. lua_pushlstring(L, (char*)(buff.b + 1), read_len - 1);
  178. lua_pushstring(L, ">f");
  179. lua_call(L, 2, 2);
  180. // _, val = pack.unpack(data, ">f")
  181. break;
  182. case LUA_TINTEGER:
  183. intVal = (lua_Integer*)(&buff.b[1]);
  184. lua_pushinteger(L, *intVal);
  185. break;
  186. case LUA_TSTRING:
  187. lua_pushlstring(L, (const char*)(buff.b + 1), read_len - 1);
  188. break;
  189. case LUA_TTABLE:
  190. lua_getglobal(L, "json");
  191. lua_getfield(L, -1, "decode");
  192. lua_pushlstring(L, (const char*)(buff.b + 1), read_len - 1);
  193. lua_call(L, 1, 1);
  194. break;
  195. default :
  196. LLOGW("bad value prefix %02X", buff.b[0]);
  197. lua_pushnil(L);
  198. break;
  199. }
  200. return 1;
  201. }
  202. lua_pushnil(L);
  203. return 1;
  204. }
  205. /**
  206. 根据key删除数据
  207. @api fdb.kv_del(key)
  208. @string key的名称,必填,不能空字符串
  209. @return bool 成功返回true,否则返回false
  210. @usage
  211. if fdb.kvdb_init("env", "onchip_fdb") then
  212. log.info("fdb", fdb.kv_del("wendal"))
  213. end
  214. */
  215. static int l_fdb_kv_del(lua_State *L) {
  216. const char* key = luaL_checkstring(L, 1);
  217. fdb_err_t ret = fdb_kv_del(&kvdb, key);
  218. lua_pushboolean(L, ret == FDB_NO_ERR ? 1 : 0);
  219. return 1;
  220. }
  221. /**
  222. 清空整个kv数据库
  223. @api fdb.kv_clr()
  224. @return bool 成功返回true,否则返回false
  225. @usage
  226. -- 清空
  227. fdb.kv_clr()
  228. */
  229. static int l_fdb_kv_clr(lua_State *L) {
  230. fdb_err_t ret = fdb_kv_set_default(&kvdb);
  231. lua_pushboolean(L, ret == FDB_NO_ERR ? 1 : 0);
  232. lua_pushinteger(L, ret);
  233. return 2;
  234. }
  235. #include "rotable2.h"
  236. static const rotable_Reg_t reg_fdb[] =
  237. {
  238. { "kvdb_init" , ROREG_FUNC(l_fdb_kvdb_init)},
  239. { "kvdb_deinit" , ROREG_FUNC(l_fdb_kvdb_deinit)},
  240. { "kv_set", ROREG_FUNC(l_fdb_kv_set)},
  241. { "kv_get", ROREG_FUNC(l_fdb_kv_get)},
  242. { "kv_del", ROREG_FUNC(l_fdb_kv_del)},
  243. { "kv_clr", ROREG_FUNC(l_fdb_kv_clr)},
  244. { NULL, ROREG_INT(0)}
  245. };
  246. LUAMOD_API int luaopen_fdb( lua_State *L ) {
  247. luat_newlib2(L, reg_fdb);
  248. return 1;
  249. }