DBTable.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:12k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "DBTable.h"
  3. #ifndef WIN32
  4. #include <sys/stat.h>
  5. #else
  6. #include <direct.h>
  7. #endif
  8. #include <stdio.h>
  9. #include <string.h>
  10. ZDBTable::ZDBTable(const char *path, const char *name) {
  11. #ifdef WIN32
  12. getcwd(env_path, MAX_TABLE_NAME);
  13. #else
  14. #endif
  15. strcat(env_path, "\");
  16. strcat(env_path, path);
  17. #ifdef WIN32
  18. int ret = mkdir(env_path);
  19. #else
  20.         int ret = mkdir(env_path, 0);
  21. #endif
  22. dbcp = NULL;//初始化游标(by Fellow)
  23. if(!db_env_create(&dbenv, 0)) {
  24. dbenv->set_errpfx(dbenv, "index_db");
  25. if(!dbenv->open(dbenv, env_path, DB_CREATE | DB_INIT_LOG | DB_INIT_LOCK | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER, 0)) {
  26. index_number = 0;
  27. strcpy(table_name, name);
  28. return; //成功了
  29. }
  30. dbenv->close(dbenv, 0);
  31. }
  32. dbenv = NULL;
  33. }
  34. ZDBTable::~ZDBTable() {
  35. if(dbenv) dbenv->close(dbenv, 0);
  36. }
  37. int ZDBTable::addIndex(GetIndexFunc func, bool isUnique) {
  38. if(!dbenv) return -1;
  39. if(index_number + 1 >= MAX_INDEX) return index_number;
  40. get_index_funcs[index_number] = func;
  41. is_index_unique[index_number] = isUnique;
  42. return index_number++;
  43. }
  44. bool ZDBTable::open() {
  45. if(!dbenv) return false;
  46. char index_table_name[MAX_TABLE_NAME];
  47.     int index;
  48. int ret;
  49. if(!db_create(&primary_db, dbenv, 0)) {
  50. if(!primary_db->open(primary_db, NULL, table_name, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT, 0664)) { //打开主数据库
  51. for(index = 0; index < index_number; index++) {
  52. sprintf(index_table_name, "%s.%d", table_name, index);
  53. if(!db_create(&index_db[index], dbenv, 0)) {
  54. if(!is_index_unique[index]) {
  55. if(index_db[index]->set_flags(index_db[index], DB_DUP | DB_DUPSORT)) break;
  56. }
  57. if(index_db[index]->open(index_db[index], NULL, index_table_name, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT, 0664)) break;
  58. if(ret = primary_db->associate(primary_db, NULL, index_db[index], get_index_funcs[index], DB_AUTO_COMMIT)) {
  59. index_db[index]->close(index_db[index], 0);
  60. break;
  61. }
  62. }
  63. else break;
  64. }
  65. if(index == index_number) return true; //成功了
  66. else while(--index) (index_db[index])->close(index_db[index], 0); //出错,关闭前面的索引表
  67. primary_db->close(primary_db, 0);
  68. }
  69. }
  70. return false;
  71. }
  72. void ZDBTable::close() {
  73. if(!dbenv) return;
  74. primary_db->close(primary_db, 0);
  75. for(int index = 0; index < index_number; index++) index_db[index]->close(index_db[index], 0);
  76. }
  77. bool ZDBTable::commit() {
  78. /* if(!dbenv) return false;
  79. int ret;
  80. DB_TXN *tid;
  81. if((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) return false;
  82. if((ret = primary_db->sync(primary_db, 0)) == 0) {
  83. ret = tid->commit(tid, 0);
  84. if(!ret) return true;
  85. }
  86. else {
  87. tid->abort(tid);
  88. return false;
  89. }*/
  90. return true;
  91. }
  92. bool ZDBTable::add(const char *key_ptr, int key_size, const char *data_ptr, int data_size) {
  93. DBT data, key;
  94. memset(&key, 0, sizeof(DBT));
  95. memset(&data, 0, sizeof(DBT));
  96. key.data = (void *)key_ptr;
  97. key.size = key_size;
  98. data.data = (void *)data_ptr;
  99. data.size = data_size;
  100. if(!primary_db->put(primary_db, NULL, &key, &data, DB_AUTO_COMMIT)) {
  101. return true;
  102. }
  103. return false;
  104. }
  105. bool ZDBTable::remove(const char *key_ptr, int key_size, int index) {
  106. DBT data, key;
  107. memset(&key, 0, sizeof(DBT));
  108. memset(&data, 0, sizeof(DBT));
  109. key.data = (void *)key_ptr;
  110. key.size = key_size;
  111. if(!primary_db->del(primary_db, NULL, &key, DB_AUTO_COMMIT)) {
  112. return true;
  113. }
  114. return false;
  115. }
  116. char *ZDBTable::_search(bool bKey, const char *key_ptr, int key_size, int &size, int index) {
  117. dbcp = NULL;
  118. DBT key, data, pkey;
  119. if(index < -1 || index >= index_number) return NULL;
  120. memset(&key, 0, sizeof(key));
  121. memset(&data, 0, sizeof(data));
  122. memset(&pkey, 0, sizeof(pkey));
  123. key.data = (void *)key_ptr;
  124. key.size = key_size;
  125. if(index == -1) { //主键搜索
  126. if(primary_db->get(primary_db, NULL, &key, &data, 0)) return NULL;
  127. }
  128. else if(is_index_unique[index]) { //没有重复索引
  129. if(bKey) {
  130. if(index_db[index]->pget(index_db[index], NULL, &key, &pkey, &data, 0)) return NULL;
  131. }
  132. else {
  133. if(index_db[index]->get(index_db[index], NULL, &key, &data, 0)) return NULL;
  134. }
  135. }
  136. else { //打开游标
  137. if(index_db[index]->cursor(index_db[index], NULL, &dbcp, 0)) {
  138. dbcp = NULL;
  139. return NULL;
  140. }
  141. if(bKey) {
  142. if(dbcp->c_pget(dbcp, &key, &pkey, &data, DB_SET)) {
  143. dbcp->c_close(dbcp);
  144. dbcp = NULL;
  145. return NULL;
  146. }
  147. }
  148. else {
  149. if(dbcp->c_get(dbcp, &key, &data, DB_SET)) {
  150. dbcp->c_close(dbcp);
  151. dbcp = NULL;
  152. return NULL;
  153. }
  154. }
  155. }
  156. char *result;
  157. if(bKey) {
  158. result = new char[pkey.size];
  159. memmove(result, pkey.data, pkey.size);
  160. size = pkey.size;
  161. }
  162. else {
  163. result = new char[data.size];
  164. memmove(result, data.data, data.size);
  165. size = data.size;
  166. }
  167. return result;
  168. }
  169. char *ZDBTable::_next(bool bKey, int &size) {
  170. if(!dbcp) return NULL;
  171. DBT key, data, pkey;
  172. memset(&key, 0, sizeof(key));
  173. memset(&data, 0, sizeof(data));
  174. memset(&pkey, 0, sizeof(pkey));
  175. if(bKey) {
  176. if(dbcp->c_pget(dbcp, &key, &pkey, &data, DB_NEXT_DUP)) {
  177. dbcp->c_close(dbcp);
  178. dbcp = NULL;
  179. return NULL;
  180. }
  181. }
  182. else {
  183. if(dbcp->c_get(dbcp, &key, &data, DB_NEXT_DUP)) {
  184. dbcp->c_close(dbcp);
  185. dbcp = NULL;
  186. return NULL;
  187. }
  188. }
  189. char *result;
  190. if(bKey) {
  191. result = new char[pkey.size];
  192. memmove(result, pkey.data, pkey.size);
  193. size = pkey.size;
  194. }
  195. else {
  196. result = new char[data.size];
  197. memmove(result, data.data, data.size);
  198. size = data.size;
  199. }
  200. return result;
  201. }
  202. char *ZDBTable::GetRecord(int &size, CursorPointer cpMode, int index )
  203. {//取得按游标某一个数据
  204. if(!dbcp)
  205. {//如果数据库指针没有初始化,先初始化dbcp
  206. if(index_db[index]->cursor(index_db[index], NULL, &dbcp, 0))
  207. {//初始化dbcp失败
  208. dbcp = NULL;
  209. return NULL;
  210. }
  211. }
  212. DBT key, data, pkey;
  213. memset(&key, 0, sizeof(key));
  214. memset(&data, 0, sizeof(data));
  215. memset(&pkey, 0, sizeof(pkey));
  216. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  217. dbcp->c_close(dbcp);
  218. dbcp = NULL;
  219. return NULL;
  220. }
  221. char *result;
  222. result = new char[data.size];
  223. memmove(result, data.data, data.size);
  224. size = data.size;
  225. return result;
  226. }
  227. char *ZDBTable::GetRecord_key(int &size, CursorPointer cpMode, int index )
  228. {
  229. if(!dbcp)
  230. {//如果数据库指针没有初始化,先初始化dbcp
  231. if(index_db[index]->cursor(index_db[index], NULL, &dbcp, 0))
  232. {//初始化dbcp失败
  233. dbcp = NULL;
  234. return NULL;
  235. }
  236. }
  237. DBT key, data, pkey;
  238. memset(&key, 0, sizeof(key));
  239. memset(&data, 0, sizeof(data));
  240. memset(&pkey, 0, sizeof(pkey));
  241. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  242. dbcp->c_close(dbcp);
  243. dbcp = NULL;
  244. return NULL;
  245. }
  246. char *result;
  247. result = new char[key.size];
  248. memmove(result, key.data, key.size);
  249. size = key.size;
  250. return result;
  251. }
  252. bool ZDBTable::GetRecordEx(char* aBuffer, int &size,
  253.    char* aKeyBuffer, int &keysize,
  254.    CursorPointer cpMode, int index)
  255. {//取得按游标某一个数据(新版函数)
  256. if(!dbcp)
  257. {//如果数据库指针没有初始化,先初始化dbcp
  258. if(index_db[index]->cursor(index_db[index], NULL, &dbcp, 0))
  259. {//初始化dbcp失败
  260. dbcp = NULL;
  261. return false;
  262. }
  263. }
  264. DBT key, data, pkey;
  265. memset(&key, 0, sizeof(key));
  266. memset(&data, 0, sizeof(data));
  267. memset(&pkey, 0, sizeof(pkey));
  268. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  269. dbcp->c_close(dbcp);
  270. dbcp = NULL;
  271. return false;
  272. }
  273. memmove(aBuffer, data.data, data.size);
  274. size = data.size;
  275. memmove(aKeyBuffer, key.data, key.size);
  276. keysize = key.size;
  277. return true;
  278. }
  279. CDBTableReadOnly::CDBTableReadOnly(const char *path, const char *name) {
  280. #ifdef WIN32
  281. getcwd(env_path, MAX_TABLE_NAME);
  282. #else
  283. #endif
  284. strcat(env_path, "\");
  285. strcat(env_path, path);
  286. #ifdef WIN32
  287. int ret = mkdir(env_path);
  288. #else
  289.         int ret = mkdir(env_path, 0);
  290. #endif
  291. dbcp = NULL;//初始化游标(by Fellow)
  292. if(!db_env_create(&dbenv, 0)) {
  293. dbenv->set_errpfx(dbenv, "index_db");
  294. if(!dbenv->open(dbenv, env_path, DB_USE_ENVIRON | DB_INIT_MPOOL, 0)) {
  295. strcpy(table_name, name);
  296. return; //成功了
  297. }
  298. dbenv->close(dbenv, 0);
  299. }
  300. dbenv = NULL;
  301. }
  302. CDBTableReadOnly::~CDBTableReadOnly() {
  303. if(dbenv) dbenv->close(dbenv, 0);
  304. }
  305. bool CDBTableReadOnly::open() {
  306. if(!dbenv) return false;
  307. if(!db_create(&primary_db, dbenv, 0)) {
  308. if(!primary_db->open(primary_db, NULL, table_name, NULL, DB_BTREE, DB_RDONLY, 0664)) { //打开主数据库
  309. return true;
  310. }
  311. }
  312. return false;
  313. }
  314. void CDBTableReadOnly::close() {
  315. if(!dbenv) return;
  316. primary_db->close(primary_db, 0);
  317. }
  318. char *CDBTableReadOnly::_search(bool bKey, const char *key_ptr, int key_size, int &size) {
  319. dbcp = NULL;
  320. DBT key, data, pkey;
  321. memset(&key, 0, sizeof(key));
  322. memset(&data, 0, sizeof(data));
  323. memset(&pkey, 0, sizeof(pkey));
  324. key.data = (void *)key_ptr;
  325. key.size = key_size;
  326. if(primary_db->get(primary_db, NULL, &key, &data, 0)) return NULL;
  327. char *result;
  328. if(bKey) {
  329. result = new char[pkey.size];
  330. memmove(result, pkey.data, pkey.size);
  331. size = pkey.size;
  332. }
  333. else {
  334. result = new char[data.size];
  335. memmove(result, data.data, data.size);
  336. size = data.size;
  337. }
  338. return result;
  339. }
  340. char *CDBTableReadOnly::_next(bool bKey, int &size) {
  341. if(!dbcp) return NULL;
  342. DBT key, data, pkey;
  343. memset(&key, 0, sizeof(key));
  344. memset(&data, 0, sizeof(data));
  345. memset(&pkey, 0, sizeof(pkey));
  346. if(bKey) {
  347. if(dbcp->c_pget(dbcp, &key, &pkey, &data, DB_NEXT_DUP)) {
  348. dbcp->c_close(dbcp);
  349. dbcp = NULL;
  350. return NULL;
  351. }
  352. }
  353. else {
  354. if(dbcp->c_get(dbcp, &key, &data, DB_NEXT_DUP)) {
  355. dbcp->c_close(dbcp);
  356. dbcp = NULL;
  357. return NULL;
  358. }
  359. }
  360. char *result;
  361. if(bKey) {
  362. result = new char[pkey.size];
  363. memmove(result, pkey.data, pkey.size);
  364. size = pkey.size;
  365. }
  366. else {
  367. result = new char[data.size];
  368. memmove(result, data.data, data.size);
  369. size = data.size;
  370. }
  371. return result;
  372. }
  373. char *CDBTableReadOnly::GetRecord(int &size, CursorPointer cpMode)
  374. {
  375. if(!dbcp)
  376. {//如果数据库指针没有初始化,先初始化dbcp
  377. if(primary_db->cursor(primary_db, NULL, &dbcp, 0))
  378. {//初始化dbcp失败
  379. dbcp = NULL;
  380. return NULL;
  381. }
  382. }
  383. DBT key, data, pkey;
  384. memset(&key, 0, sizeof(key));
  385. memset(&data, 0, sizeof(data));
  386. memset(&pkey, 0, sizeof(pkey));
  387. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  388. dbcp->c_close(dbcp);
  389. dbcp = NULL;
  390. return NULL;
  391. }
  392. char *result;
  393. result = new char[data.size];
  394. memmove(result, data.data, data.size);
  395. size = data.size;
  396. return result;
  397. }
  398. char *CDBTableReadOnly::GetRecord_key(int &size, CursorPointer cpMode)
  399. {
  400. if(!dbcp)
  401. {//如果数据库指针没有初始化,先初始化dbcp
  402. if(primary_db->cursor(primary_db, NULL, &dbcp, 0))
  403. {//初始化dbcp失败
  404. dbcp = NULL;
  405. return NULL;
  406. }
  407. }
  408. DBT key, data, pkey;
  409. memset(&key, 0, sizeof(key));
  410. memset(&data, 0, sizeof(data));
  411. memset(&pkey, 0, sizeof(pkey));
  412. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  413. dbcp->c_close(dbcp);
  414. dbcp = NULL;
  415. return NULL;
  416. }
  417. char *result;
  418. result = new char[key.size];
  419. memmove(result, key.data, key.size);
  420. size = key.size;
  421. return result;
  422. }
  423. bool CDBTableReadOnly::GetRecordEx(char* aBuffer, int &size,
  424.    char* aKeyBuffer, int &keysize,
  425.    CursorPointer cpMode)
  426. {//取得按游标某一个数据(新版函数)
  427. if(!dbcp)
  428. {//如果数据库指针没有初始化,先初始化dbcp
  429. if(primary_db->cursor(primary_db, NULL, &dbcp, 0))
  430. {//初始化dbcp失败
  431. dbcp = NULL;
  432. return false;
  433. }
  434. }
  435. DBT key, data, pkey;
  436. memset(&key, 0, sizeof(key));
  437. memset(&data, 0, sizeof(data));
  438. memset(&pkey, 0, sizeof(pkey));
  439. if(dbcp->c_get(dbcp, &key, &data, cpMode)) {
  440. dbcp->c_close(dbcp);
  441. dbcp = NULL;
  442. return false;
  443. }
  444. memmove(aBuffer, data.data, data.size);
  445. size = data.size;
  446. memmove(aKeyBuffer, key.data, key.size);
  447. keysize = key.size;
  448. return true;
  449. }