ldb.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. use std::ops::{Deref, DerefMut};
  2. use std::ptr::null;
  3. use lua_shared as lua;
  4. use lua_shared::lua_State;
  5. use crate::ltree::LTree;
  6. use crate::lua_struct::StructError;
  7. use crate::{check_slice, insert_function, lua_struct, tree_get_key, tree_get_no_arg};
  8. #[derive(Debug, Clone)]
  9. pub struct LDb(pub sled::Db);
  10. impl Deref for LDb {
  11. type Target = sled::Db;
  12. fn deref(&self) -> &Self::Target {
  13. &self.0
  14. }
  15. }
  16. impl DerefMut for LDb {
  17. fn deref_mut(&mut self) -> &mut sled::Db {
  18. &mut self.0
  19. }
  20. }
  21. impl LDb {
  22. pub fn l_open(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  23. unsafe {
  24. let db = sled::open(std::str::from_utf8_unchecked(check_slice!(state, 1)))?;
  25. let ldb = lua::newuserdata(state, std::mem::size_of::<Self>()).cast::<Self>();
  26. ldb.write(Self(db));
  27. Self::metatable(state);
  28. lua::setmetatable(state, -2);
  29. }
  30. Ok(1)
  31. }
  32. fn lm_name(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  33. unsafe {
  34. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  35. let name = this.name();
  36. lua::pushlstring(state, name.as_ptr(), name.len());
  37. Ok(1)
  38. }
  39. }
  40. fn lm_clear(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  41. unsafe {
  42. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  43. this.clear()?;
  44. Ok(0)
  45. }
  46. }
  47. fn lm_get(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  48. unsafe {
  49. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  50. if let Some(ivec) = this.0.get(check_slice!(state, 2))? {
  51. lua::pushlstring(state, ivec.as_ptr(), ivec.len());
  52. Ok(1)
  53. } else {
  54. Ok(0)
  55. }
  56. }
  57. }
  58. fn lm_get_struct(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  59. unsafe {
  60. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  61. let key = check_slice!(state, 2);
  62. let fmt = check_slice!(state, 3);
  63. if let Some(ivec) = this.0.get(key)? {
  64. match lua_struct::unpack(state, fmt, &ivec) {
  65. Ok(args) => Ok(args),
  66. Err(e) => {
  67. drop(ivec);
  68. match e {
  69. StructError::Error(e) => lua::Lerror(state, e),
  70. StructError::ArgError(arg, e) => lua::Largerror(state, arg, e),
  71. StructError::InvalidFormatOption(e, opt) => lua::Lerror(state, e, opt),
  72. StructError::IOError(e) => return Err(e)?,
  73. }
  74. }
  75. }
  76. } else {
  77. lua::pushnil(state);
  78. Ok(1)
  79. }
  80. }
  81. }
  82. fn lm_insert(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  83. unsafe {
  84. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  85. this.insert(check_slice!(state, 2), check_slice!(state, 3))?;
  86. Ok(0)
  87. }
  88. }
  89. fn lm_insert_struct(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  90. unsafe {
  91. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  92. let key = check_slice!(state, 2);
  93. let fmt = check_slice!(state, 3);
  94. let value = match lua_struct::pack(state, fmt, 4) {
  95. Ok(result) => result,
  96. Err(StructError::Error(e)) => lua::Lerror(state, e),
  97. Err(StructError::ArgError(arg, e)) => lua::Largerror(state, arg, e),
  98. Err(StructError::InvalidFormatOption(e, opt)) => lua::Lerror(state, e, opt),
  99. Err(StructError::IOError(e)) => return Err(e)?,
  100. };
  101. this.insert(key, value)?;
  102. Ok(0)
  103. }
  104. }
  105. fn lm_remove(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  106. unsafe {
  107. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  108. this.remove(check_slice!(state, 2))?;
  109. Ok(0)
  110. }
  111. }
  112. fn lm_range(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  113. unsafe {
  114. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  115. let mut range = this.range(check_slice!(state, 2)..=check_slice!(state, 3));
  116. lua::pushfunction(state, move |state| {
  117. if let Some(tree_name) = range.next() {
  118. let (key, value) = tree_name?;
  119. lua::pushlstring(state, key.as_ptr(), key.len());
  120. lua::pushlstring(state, value.as_ptr(), value.len());
  121. Ok(2)
  122. } else {
  123. Ok(0)
  124. }
  125. });
  126. Ok(1)
  127. }
  128. }
  129. fn lm_scan_prefix(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  130. unsafe {
  131. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  132. let prefix = {
  133. let mut len = 0;
  134. std::slice::from_raw_parts(lua::Loptlstring(state, 2, null(), &mut len), len)
  135. };
  136. let mut prefix = this.scan_prefix(prefix);
  137. lua::pushfunction(state, move |state| {
  138. if let Some(tree_name) = prefix.next() {
  139. let (key, value) = tree_name?;
  140. lua::pushlstring(state, key.as_ptr(), key.len());
  141. lua::pushlstring(state, value.as_ptr(), value.len());
  142. Ok(2)
  143. } else {
  144. Ok(0)
  145. }
  146. });
  147. Ok(1)
  148. }
  149. }
  150. fn lm_tree_names(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  151. unsafe {
  152. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  153. let mut iter = this.0.tree_names().into_iter();
  154. lua::pushfunction(state, move |state| {
  155. if let Some(tree_name) = iter.next() {
  156. lua::pushlstring(state, tree_name.as_ptr(), tree_name.len());
  157. Ok(1)
  158. } else {
  159. Ok(0)
  160. }
  161. });
  162. Ok(1)
  163. }
  164. }
  165. fn lm_open_tree(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  166. unsafe {
  167. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  168. let tree = this.open_tree(std::str::from_utf8_unchecked(check_slice!(state, 2)))?;
  169. let ltree = lua::newuserdata(state, std::mem::size_of::<LTree>()).cast::<LTree>();
  170. ltree.write(LTree(tree));
  171. LTree::metatable(state);
  172. lua::setmetatable(state, -2);
  173. Ok(1)
  174. }
  175. }
  176. fn lm_drop_tree(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  177. unsafe {
  178. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  179. lua::pushboolean(
  180. state,
  181. this.drop_tree(std::str::from_utf8_unchecked(check_slice!(state, 2)))? as _,
  182. );
  183. Ok(1)
  184. }
  185. }
  186. fn lm_was_recovered(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  187. unsafe {
  188. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  189. lua::pushboolean(state, this.0.was_recovered() as _);
  190. Ok(1)
  191. }
  192. }
  193. fn lm_size_on_disk(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  194. unsafe {
  195. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  196. lua::pushinteger(state, this.size_on_disk()? as _);
  197. Ok(1)
  198. }
  199. }
  200. fn lm_generate_id(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  201. unsafe {
  202. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  203. lua::pushnumber(state, this.generate_id()? as _);
  204. Ok(1)
  205. }
  206. }
  207. fn lm_export(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  208. unsafe {
  209. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  210. let export: Vec<(Vec<u8>, Vec<u8>, Vec<Vec<Vec<u8>>>)> = this
  211. .export()
  212. .into_iter()
  213. .map(|(collection, name, kv)| {
  214. (
  215. collection,
  216. name,
  217. kv.into_iter().collect::<Vec<Vec<Vec<u8>>>>(),
  218. )
  219. })
  220. .collect();
  221. let blob = bincode::serialize(&export)?;
  222. lua::pushlstring(state, blob.as_ptr(), blob.len());
  223. Ok(1)
  224. }
  225. }
  226. fn lm_import(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  227. unsafe {
  228. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  229. let blob = check_slice!(state, 2);
  230. let import: Vec<(Vec<u8>, Vec<u8>, Vec<Vec<Vec<u8>>>)> = bincode::deserialize(blob)?;
  231. this.import(
  232. import
  233. .into_iter()
  234. .map(|(collection, name, kv)| (collection, name, kv.into_iter()))
  235. .collect(),
  236. );
  237. Ok(0)
  238. }
  239. }
  240. fn lm_flush(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  241. unsafe {
  242. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  243. lua::pushinteger(state, this.flush()? as _);
  244. Ok(1)
  245. }
  246. }
  247. fn lm_checksum(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  248. unsafe {
  249. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  250. lua::pushinteger(state, this.checksum()? as _);
  251. Ok(1)
  252. }
  253. }
  254. fn lm_contains_key(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  255. unsafe {
  256. let this = &mut *lua::Lcheckudata(state, 1, lua::cstr!("csldb")).cast::<Self>();
  257. let key = check_slice!(state, 2);
  258. lua::pushboolean(state, this.contains_key(key)? as _);
  259. Ok(1)
  260. }
  261. }
  262. tree_get_key!(get_lt get_gt, "csldb");
  263. tree_get_no_arg!(first last pop_max pop_min, "csldb");
  264. fn __gc(state: lua_State) -> Result<i32, Box<dyn std::error::Error>> {
  265. unsafe {
  266. let _ = lua::Lcheckudata(state, 1, lua::cstr!("csldb"))
  267. .cast::<Self>()
  268. .read();
  269. Ok(0)
  270. }
  271. }
  272. fn metatable(state: lua_State) {
  273. unsafe {
  274. if lua::Lnewmetatable(state, lua::cstr!("csldb")) {
  275. lua::pushvalue(state, -1);
  276. lua::setfield(state, -2, lua::cstr!("__index"));
  277. insert_function!(state, "__gc", Self::__gc);
  278. insert_function!(state, "Name", Self::lm_name);
  279. insert_function!(state, "Clear", Self::lm_clear);
  280. insert_function!(state, "Get", Self::lm_get);
  281. insert_function!(state, "GetStruct", Self::lm_get_struct);
  282. insert_function!(state, "Insert", Self::lm_insert);
  283. insert_function!(state, "InsertStruct", Self::lm_insert_struct);
  284. insert_function!(state, "Remove", Self::lm_remove);
  285. insert_function!(state, "Range", Self::lm_range);
  286. insert_function!(state, "ScanPrefix", Self::lm_scan_prefix);
  287. insert_function!(state, "TreeNames", Self::lm_tree_names);
  288. insert_function!(state, "OpenTree", Self::lm_open_tree);
  289. insert_function!(state, "GenerateID", Self::lm_generate_id);
  290. insert_function!(state, "Export", Self::lm_export);
  291. insert_function!(state, "Import", Self::lm_import);
  292. insert_function!(state, "DropTree", Self::lm_drop_tree);
  293. insert_function!(state, "WasRecovered", Self::lm_was_recovered);
  294. insert_function!(state, "SizeOnDisk", Self::lm_size_on_disk);
  295. insert_function!(state, "Flush", Self::lm_flush);
  296. insert_function!(state, "Checksum", Self::lm_checksum);
  297. insert_function!(state, "ContainsKey", Self::lm_contains_key);
  298. insert_function!(state, "GetLT", Self::lm_get_lt);
  299. insert_function!(state, "GetLTStruct", Self::lm_get_lt_struct);
  300. insert_function!(state, "GetGT", Self::lm_get_gt);
  301. insert_function!(state, "GetGTStruct", Self::lm_get_gt_struct);
  302. insert_function!(state, "First", Self::lm_first);
  303. insert_function!(state, "FirstStruct", Self::lm_first_struct);
  304. insert_function!(state, "Last", Self::lm_last);
  305. insert_function!(state, "LastStruct", Self::lm_last_struct);
  306. insert_function!(state, "PopMax", Self::lm_pop_max);
  307. insert_function!(state, "PopMaxStruct", Self::lm_pop_max_struct);
  308. insert_function!(state, "PopMin", Self::lm_pop_min);
  309. insert_function!(state, "PopMinStruct", Self::lm_pop_min_struct);
  310. }
  311. }
  312. }
  313. }