symisc / unqlite

An Embedded NoSQL, Transactional Database Engine
https://unqlite.symisc.net
Other
2.09k stars 163 forks source link

Multiple Instance #122

Open leesinje opened 3 years ago

leesinje commented 3 years ago

Hello, I want to use Unqlite Database between two processes, one is for writing and the other is for reading. To test that, I made the below codes. When I tested at Visual Studio2019, Windows 10, (// Retrieve Data with pDb2) unqlite_kv_cursor_init function at line 87 was failed with return code SXERR_BUSY(-14). What should I do to run correctly without closing the pDb2? Please advise me. Thank you.


1. // unqlite_test.cpp : This file contains the 'main' function. Program execution begins and ends there.
2. 
3.   #include <iostream>
4.   #include <string>
5.   #include <unqlite.h>
6.   int DataConsumerCallback(const void*, unsigned int, void *);
7. 
8.   int main()
9.   {
10.     int i, rc;
11.     unqlite* pDb1 = nullptr, *pDb2 = nullptr;
12.     unqlite_kv_cursor* pCursor1 = nullptr, *pCursor2 = nullptr;
13.     unqlite_int64 iData;
14. 
15.     // Open two db instance(pDb1 readwrite and pDb2 readonly)
16.     // Open readwrite database;
17.     rc = unqlite_open(&pDb1, "c:\\temp\\test.db", UNQLITE_OPEN_CREATE);
18.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
19. 
20.     // Open another database;
21.     rc = unqlite_open(&pDb2, "c:\\temp\\test.db", UNQLITE_OPEN_READONLY);
22.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
23. 
24.     //Store 20 random records into pDb1
25.     for (i = 0; i < 20; ++i) {
26.         char zKey[12]; //Random generated key
27.         char zData[34]; //Dummy data
28. 
29.         // generate the random key
30.         unqlite_util_random_string(pDb1, zKey, sizeof(zKey));
31.         unqlite_util_random_string(pDb1, zData, sizeof(zData));
32. 
33.         // Perform the insertion
34.         rc = unqlite_kv_store(pDb1, zKey, sizeof(zKey), zData, sizeof(zData));
35.         if (rc != UNQLITE_OK)   goto UNQLITE_END;
36.     }
37.     rc = unqlite_commit(pDb1);
38.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
39. 
40.     // Retrieve Data with pDb2
41.     rc = unqlite_kv_cursor_init(pDb2, &pCursor1);
42.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
43. 
44.     for ( unqlite_kv_cursor_first_entry(pCursor1) ; unqlite_kv_cursor_valid_entry(pCursor1) ; unqlite_kv_cursor_next_entry(pCursor1) ) 
45.     {
46.         // Consume the key
47.         printf("\nKey ==>\n\t");
48.         unqlite_kv_cursor_key_callback(pCursor1, DataConsumerCallback, 0);
49. 
50.         // Extract data length
51.         unqlite_kv_cursor_data(pCursor1, NULL, &iData);
52. 
53.         printf("\nData length ==> %lld\n\t", iData);
54.         // Consume the data
55.         unqlite_kv_cursor_data_callback(pCursor1, DataConsumerCallback, 0);
56. 
57.     }
58. 
59.     rc = unqlite_kv_cursor_release(pDb2, pCursor1);
60.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
61.     /*
62.         rc = unqlite_close(pDb2);
63.         if (rc != UNQLITE_OK)   goto UNQLITE_END;
64.         // Open another database;
65.         rc = unqlite_open(&pDb2, "c:\\temp\\test.db", UNQLITE_OPEN_READONLY);
66.         if (rc != UNQLITE_OK)   goto UNQLITE_END;
67.     */
68. 
69.     // Store another records with pDb1
70.     for (i = 0; i < 20; ++i) {
71.         char zKey[12]; //Random generated key
72.         char zData[34]; //Dummy data
73. 
74.         // generate the random key
75.         unqlite_util_random_string(pDb1, zKey, sizeof(zKey));
76.         unqlite_util_random_string(pDb1, zData, sizeof(zData));
77. 
78.         // Perform the insertion
79.         rc = unqlite_kv_store(pDb1, zKey, sizeof(zKey), zData, sizeof(zData));
80.         if (rc != UNQLITE_OK)   goto UNQLITE_END;
81.     }
82. 
83.     rc = unqlite_commit(pDb1);
84.     if (rc != UNQLITE_OK)   goto UNQLITE_END;
85. 
86.    **_// Retrieve Data with pDb2
87.     rc = unqlite_kv_cursor_init(pDb2, &pCursor2);
88.     if (rc != UNQLITE_OK)   goto UNQLITE_END;_**
89. 
90.     for (unqlite_kv_cursor_first_entry(pCursor2); unqlite_kv_cursor_valid_entry(pCursor2); unqlite_kv_cursor_next_entry(pCursor2))
91.     {
92.         // Consume the key
93.         printf("\nKey ==>\n\t");
94.         unqlite_kv_cursor_key_callback(pCursor2, DataConsumerCallback, 0);
95. 
96.         // Extract data length
97.         unqlite_kv_cursor_data(pCursor2, NULL, &iData);
98. 
99.         printf("\nData length ==> %lld\n\t", iData);
100.         // Consume the data
101.         unqlite_kv_cursor_data_callback(pCursor2, DataConsumerCallback, 0);
102.     }
103. 
104.     unqlite_kv_cursor_release(pDb2, pCursor2);
105.     unqlite_close(pDb2);
106. 
107.   UNQLITE_END:
108.     unqlite_close(pDb1);
109.   }
110. 
111.   int DataConsumerCallback(const void* pData, unsigned int iDataLen, void* pUserData)
112.   {
113.     char data[128];
114.     if( pData != nullptr && iDataLen != 0 )
115.     {
116.         strncpy_s(data, 128, (const char*)pData, iDataLen);
117.         printf(data);
118.         printf("\n");
119.     }
120.     return 0;
121.  }
symisc commented 3 years ago

Hi,

unqlite_kv_cursor_init() never fails with the UNQLITE_BUSY error code. Could you check again where this error code is raised from?