@joystick.js/db-canary 0.0.0-canary.2251 → 0.0.0-canary.2252
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/database.js +1 -1
- package/dist/client/index.js +1 -1
- package/dist/server/cluster/master.js +4 -4
- package/dist/server/cluster/worker.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/lib/auto_index_manager.js +1 -1
- package/dist/server/lib/backup_manager.js +1 -1
- package/dist/server/lib/index_manager.js +1 -1
- package/dist/server/lib/operation_dispatcher.js +1 -1
- package/dist/server/lib/operations/admin.js +1 -1
- package/dist/server/lib/operations/bulk_write.js +1 -1
- package/dist/server/lib/operations/create_index.js +1 -1
- package/dist/server/lib/operations/delete_many.js +1 -1
- package/dist/server/lib/operations/delete_one.js +1 -1
- package/dist/server/lib/operations/find.js +1 -1
- package/dist/server/lib/operations/find_one.js +1 -1
- package/dist/server/lib/operations/insert_one.js +1 -1
- package/dist/server/lib/operations/update_one.js +1 -1
- package/dist/server/lib/send_response.js +1 -1
- package/dist/server/lib/tcp_protocol.js +1 -1
- package/package.json +2 -2
- package/src/client/database.js +92 -119
- package/src/client/index.js +279 -345
- package/src/server/cluster/master.js +265 -156
- package/src/server/cluster/worker.js +26 -18
- package/src/server/index.js +553 -330
- package/src/server/lib/auto_index_manager.js +85 -23
- package/src/server/lib/backup_manager.js +117 -70
- package/src/server/lib/index_manager.js +63 -25
- package/src/server/lib/operation_dispatcher.js +339 -168
- package/src/server/lib/operations/admin.js +343 -205
- package/src/server/lib/operations/bulk_write.js +458 -194
- package/src/server/lib/operations/create_index.js +127 -34
- package/src/server/lib/operations/delete_many.js +204 -67
- package/src/server/lib/operations/delete_one.js +164 -52
- package/src/server/lib/operations/find.js +552 -319
- package/src/server/lib/operations/find_one.js +530 -304
- package/src/server/lib/operations/insert_one.js +147 -52
- package/src/server/lib/operations/update_one.js +334 -93
- package/src/server/lib/send_response.js +37 -17
- package/src/server/lib/tcp_protocol.js +158 -53
- package/test_data_api_key_1758233848259_cglfjzhou/data.mdb +0 -0
- package/test_data_api_key_1758233848259_cglfjzhou/lock.mdb +0 -0
- package/test_data_api_key_1758233848502_urlje2utd/data.mdb +0 -0
- package/test_data_api_key_1758233848502_urlje2utd/lock.mdb +0 -0
- package/test_data_api_key_1758233848738_mtcpfe5ns/data.mdb +0 -0
- package/test_data_api_key_1758233848738_mtcpfe5ns/lock.mdb +0 -0
- package/test_data_api_key_1758233848856_9g97p6gag/data.mdb +0 -0
- package/test_data_api_key_1758233848856_9g97p6gag/lock.mdb +0 -0
- package/test_data_api_key_1758233857008_0tl9zzhj8/data.mdb +0 -0
- package/test_data_api_key_1758233857008_0tl9zzhj8/lock.mdb +0 -0
- package/test_data_api_key_1758233857120_60c2f2uhu/data.mdb +0 -0
- package/test_data_api_key_1758233857120_60c2f2uhu/lock.mdb +0 -0
- package/test_data_api_key_1758233857232_aw7fkqgd9/data.mdb +0 -0
- package/test_data_api_key_1758233857232_aw7fkqgd9/lock.mdb +0 -0
- package/test_data_api_key_1758234881285_4aeflubjb/data.mdb +0 -0
- package/test_data_api_key_1758234881285_4aeflubjb/lock.mdb +0 -0
- package/test_data_api_key_1758234881520_kb0amvtqb/data.mdb +0 -0
- package/test_data_api_key_1758234881520_kb0amvtqb/lock.mdb +0 -0
- package/test_data_api_key_1758234881756_k04gfv2va/data.mdb +0 -0
- package/test_data_api_key_1758234881756_k04gfv2va/lock.mdb +0 -0
- package/test_data_api_key_1758234881876_wn90dpo1z/data.mdb +0 -0
- package/test_data_api_key_1758234881876_wn90dpo1z/lock.mdb +0 -0
- package/test_data_api_key_1758234889461_26xz3dmbr/data.mdb +0 -0
- package/test_data_api_key_1758234889461_26xz3dmbr/lock.mdb +0 -0
- package/test_data_api_key_1758234889572_uziz7e0p5/data.mdb +0 -0
- package/test_data_api_key_1758234889572_uziz7e0p5/lock.mdb +0 -0
- package/test_data_api_key_1758234889684_5f9wmposh/data.mdb +0 -0
- package/test_data_api_key_1758234889684_5f9wmposh/lock.mdb +0 -0
- package/test_data_api_key_1758235657729_prwgm6mxr/data.mdb +0 -0
- package/test_data_api_key_1758235657729_prwgm6mxr/lock.mdb +0 -0
- package/test_data_api_key_1758235657961_rc2da0dc2/data.mdb +0 -0
- package/test_data_api_key_1758235657961_rc2da0dc2/lock.mdb +0 -0
- package/test_data_api_key_1758235658193_oqqxm0sny/data.mdb +0 -0
- package/test_data_api_key_1758235658193_oqqxm0sny/lock.mdb +0 -0
- package/test_data_api_key_1758235658309_vggac1pj6/data.mdb +0 -0
- package/test_data_api_key_1758235658309_vggac1pj6/lock.mdb +0 -0
- package/test_data_api_key_1758235665968_61ko07dd1/data.mdb +0 -0
- package/test_data_api_key_1758235665968_61ko07dd1/lock.mdb +0 -0
- package/test_data_api_key_1758235666082_50lrt6sq8/data.mdb +0 -0
- package/test_data_api_key_1758235666082_50lrt6sq8/lock.mdb +0 -0
- package/test_data_api_key_1758235666194_ykvauwlzh/data.mdb +0 -0
- package/test_data_api_key_1758235666194_ykvauwlzh/lock.mdb +0 -0
- package/test_data_api_key_1758236187207_9c4paeh09/data.mdb +0 -0
- package/test_data_api_key_1758236187207_9c4paeh09/lock.mdb +0 -0
- package/test_data_api_key_1758236187441_4n3o3gkkl/data.mdb +0 -0
- package/test_data_api_key_1758236187441_4n3o3gkkl/lock.mdb +0 -0
- package/test_data_api_key_1758236187672_jt6b21ye0/data.mdb +0 -0
- package/test_data_api_key_1758236187672_jt6b21ye0/lock.mdb +0 -0
- package/test_data_api_key_1758236187788_oo84fz9u6/data.mdb +0 -0
- package/test_data_api_key_1758236187788_oo84fz9u6/lock.mdb +0 -0
- package/test_data_api_key_1758236195507_o9zeznwlm/data.mdb +0 -0
- package/test_data_api_key_1758236195507_o9zeznwlm/lock.mdb +0 -0
- package/test_data_api_key_1758236195619_qsqd60y41/data.mdb +0 -0
- package/test_data_api_key_1758236195619_qsqd60y41/lock.mdb +0 -0
- package/test_data_api_key_1758236195731_im13iq284/data.mdb +0 -0
- package/test_data_api_key_1758236195731_im13iq284/lock.mdb +0 -0
|
@@ -5,6 +5,62 @@ import create_logger from '../logger.js';
|
|
|
5
5
|
|
|
6
6
|
const { create_context_logger } = create_logger('delete_one');
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Validates database name parameter.
|
|
10
|
+
* @param {string} database_name - Database name to validate
|
|
11
|
+
* @throws {Error} When database name is missing
|
|
12
|
+
*/
|
|
13
|
+
const validate_database_name = (database_name) => {
|
|
14
|
+
if (!database_name) {
|
|
15
|
+
throw new Error('Database name is required');
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Validates collection name parameter.
|
|
21
|
+
* @param {string} collection_name - Collection name to validate
|
|
22
|
+
* @throws {Error} When collection name is missing
|
|
23
|
+
*/
|
|
24
|
+
const validate_collection_name = (collection_name) => {
|
|
25
|
+
if (!collection_name) {
|
|
26
|
+
throw new Error('Collection name is required');
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validates filter parameter.
|
|
32
|
+
* @param {Object} filter - Filter to validate
|
|
33
|
+
* @throws {Error} When filter is invalid
|
|
34
|
+
*/
|
|
35
|
+
const validate_filter = (filter) => {
|
|
36
|
+
if (!filter || typeof filter !== 'object') {
|
|
37
|
+
throw new Error('Filter must be a valid object');
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validates all delete operation parameters.
|
|
43
|
+
* @param {string} database_name - Database name
|
|
44
|
+
* @param {string} collection_name - Collection name
|
|
45
|
+
* @param {Object} filter - Filter criteria
|
|
46
|
+
*/
|
|
47
|
+
const validate_delete_parameters = (database_name, collection_name, filter) => {
|
|
48
|
+
validate_database_name(database_name);
|
|
49
|
+
validate_collection_name(collection_name);
|
|
50
|
+
validate_filter(filter);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Checks if document field matches filter value.
|
|
55
|
+
* @param {Object} document - Document to check
|
|
56
|
+
* @param {string} field - Field name
|
|
57
|
+
* @param {any} value - Expected value
|
|
58
|
+
* @returns {boolean} True if field matches value
|
|
59
|
+
*/
|
|
60
|
+
const field_matches_value = (document, field, value) => {
|
|
61
|
+
return document[field] === value;
|
|
62
|
+
};
|
|
63
|
+
|
|
8
64
|
/**
|
|
9
65
|
* Checks if a document matches the given filter criteria (simple equality check).
|
|
10
66
|
* @param {Object} document - Document to test
|
|
@@ -17,7 +73,7 @@ const matches_filter = (document, filter) => {
|
|
|
17
73
|
}
|
|
18
74
|
|
|
19
75
|
for (const [field, value] of Object.entries(filter)) {
|
|
20
|
-
if (document
|
|
76
|
+
if (!field_matches_value(document, field, value)) {
|
|
21
77
|
return false;
|
|
22
78
|
}
|
|
23
79
|
}
|
|
@@ -26,67 +82,127 @@ const matches_filter = (document, filter) => {
|
|
|
26
82
|
};
|
|
27
83
|
|
|
28
84
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @param {string}
|
|
31
|
-
* @
|
|
32
|
-
* @param {Object} filter - Filter criteria to match document for deletion
|
|
33
|
-
* @param {Object} [options={}] - Delete options (currently unused)
|
|
34
|
-
* @returns {Promise<Object>} Delete result with acknowledged and deleted_count
|
|
35
|
-
* @throws {Error} When database name, collection name is missing or filter is invalid
|
|
85
|
+
* Attempts to parse document from JSON string.
|
|
86
|
+
* @param {string} value - JSON string
|
|
87
|
+
* @returns {Object|null} Parsed document or null
|
|
36
88
|
*/
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!collection_name) {
|
|
45
|
-
throw new Error('Collection name is required');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!filter || typeof filter !== 'object') {
|
|
49
|
-
throw new Error('Filter must be a valid object');
|
|
89
|
+
const parse_document_safely = (value) => {
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(value);
|
|
92
|
+
} catch (parse_error) {
|
|
93
|
+
return null;
|
|
50
94
|
}
|
|
51
|
-
|
|
52
|
-
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Searches for and deletes matching document within transaction.
|
|
99
|
+
* @param {Object} db - Database instance
|
|
100
|
+
* @param {string} database_name - Database name
|
|
101
|
+
* @param {string} collection_name - Collection name
|
|
102
|
+
* @param {Object} filter - Filter criteria
|
|
103
|
+
* @returns {Object} Delete result with count and deleted document
|
|
104
|
+
*/
|
|
105
|
+
const find_and_delete_document = (db, database_name, collection_name, filter) => {
|
|
53
106
|
let deleted_count = 0;
|
|
54
107
|
let deleted_document = null;
|
|
55
108
|
|
|
56
|
-
|
|
57
|
-
|
|
109
|
+
const collection_prefix = `${database_name}:${collection_name}:`;
|
|
110
|
+
const range = db.getRange({ start: collection_prefix, end: collection_prefix + '\xFF' });
|
|
111
|
+
|
|
112
|
+
for (const { key, value } of range) {
|
|
113
|
+
const document = parse_document_safely(value);
|
|
114
|
+
if (!document) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
58
117
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
db.remove(key);
|
|
65
|
-
deleted_document = document;
|
|
66
|
-
deleted_count = 1;
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
} catch (parse_error) {
|
|
70
|
-
// Skip documents that can't be parsed
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
118
|
+
if (matches_filter(document, filter)) {
|
|
119
|
+
db.remove(key);
|
|
120
|
+
deleted_document = document;
|
|
121
|
+
deleted_count = 1;
|
|
122
|
+
break;
|
|
73
123
|
}
|
|
74
|
-
}
|
|
124
|
+
}
|
|
75
125
|
|
|
126
|
+
return { deleted_count, deleted_document };
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Updates indexes after document deletion.
|
|
131
|
+
* @param {string} database_name - Database name
|
|
132
|
+
* @param {string} collection_name - Collection name
|
|
133
|
+
* @param {Object} deleted_document - Deleted document
|
|
134
|
+
*/
|
|
135
|
+
const update_indexes_after_deletion = async (database_name, collection_name, deleted_document) => {
|
|
76
136
|
if (deleted_document) {
|
|
77
137
|
await update_indexes_on_delete(database_name, collection_name, deleted_document);
|
|
78
138
|
}
|
|
79
|
-
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Logs delete operation completion.
|
|
143
|
+
* @param {Function} log - Logger function
|
|
144
|
+
* @param {string} database_name - Database name
|
|
145
|
+
* @param {string} collection_name - Collection name
|
|
146
|
+
* @param {number} deleted_count - Number of deleted documents
|
|
147
|
+
*/
|
|
148
|
+
const log_delete_completion = (log, database_name, collection_name, deleted_count) => {
|
|
80
149
|
log.info('Delete operation completed', {
|
|
81
150
|
database: database_name,
|
|
82
151
|
collection: collection_name,
|
|
83
152
|
deleted_count
|
|
84
153
|
});
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Creates delete operation result.
|
|
158
|
+
* @param {number} deleted_count - Number of deleted documents
|
|
159
|
+
* @returns {Object} Delete result object
|
|
160
|
+
*/
|
|
161
|
+
const create_delete_result = (deleted_count) => ({
|
|
162
|
+
acknowledged: true,
|
|
163
|
+
deleted_count
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Creates write queue operation metadata.
|
|
168
|
+
* @param {string} database_name - Database name
|
|
169
|
+
* @param {string} collection_name - Collection name
|
|
170
|
+
* @param {Object} filter - Filter criteria
|
|
171
|
+
* @returns {Object} Operation metadata
|
|
172
|
+
*/
|
|
173
|
+
const create_write_queue_metadata = (database_name, collection_name, filter) => ({
|
|
174
|
+
operation: 'delete_one',
|
|
175
|
+
database: database_name,
|
|
176
|
+
collection: collection_name,
|
|
177
|
+
filter_keys: Object.keys(filter || {})
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Internal implementation of delete_one operation without write queue serialization.
|
|
182
|
+
* @param {string} database_name - Name of the database
|
|
183
|
+
* @param {string} collection_name - Name of the collection
|
|
184
|
+
* @param {Object} filter - Filter criteria to match document for deletion
|
|
185
|
+
* @param {Object} options - Delete options (currently unused)
|
|
186
|
+
* @returns {Promise<Object>} Delete result with acknowledged and deleted_count
|
|
187
|
+
*/
|
|
188
|
+
const delete_one_internal = async (database_name, collection_name, filter, options = {}) => {
|
|
189
|
+
const log = create_context_logger();
|
|
190
|
+
|
|
191
|
+
validate_delete_parameters(database_name, collection_name, filter);
|
|
192
|
+
|
|
193
|
+
const db = get_database();
|
|
194
|
+
|
|
195
|
+
const delete_result = await db.transaction(() => {
|
|
196
|
+
return find_and_delete_document(db, database_name, collection_name, filter);
|
|
197
|
+
});
|
|
85
198
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
199
|
+
const { deleted_count, deleted_document } = delete_result;
|
|
200
|
+
|
|
201
|
+
await update_indexes_after_deletion(database_name, collection_name, deleted_document);
|
|
202
|
+
|
|
203
|
+
log_delete_completion(log, database_name, collection_name, deleted_count);
|
|
204
|
+
|
|
205
|
+
return create_delete_result(deleted_count);
|
|
90
206
|
};
|
|
91
207
|
|
|
92
208
|
/**
|
|
@@ -94,20 +210,16 @@ const delete_one_internal = async (database_name, collection_name, filter, optio
|
|
|
94
210
|
* @param {string} database_name - Name of the database
|
|
95
211
|
* @param {string} collection_name - Name of the collection
|
|
96
212
|
* @param {Object} filter - Filter criteria to match document for deletion
|
|
97
|
-
* @param {Object}
|
|
213
|
+
* @param {Object} options - Delete options
|
|
98
214
|
* @returns {Promise<Object>} Delete result with acknowledged and deleted_count
|
|
99
215
|
*/
|
|
100
216
|
const delete_one = async (database_name, collection_name, filter, options = {}) => {
|
|
101
217
|
const write_queue = get_write_queue();
|
|
218
|
+
const operation_metadata = create_write_queue_metadata(database_name, collection_name, filter);
|
|
102
219
|
|
|
103
220
|
return await write_queue.enqueue_write_operation(
|
|
104
221
|
() => delete_one_internal(database_name, collection_name, filter, options),
|
|
105
|
-
|
|
106
|
-
operation: 'delete_one',
|
|
107
|
-
database: database_name,
|
|
108
|
-
collection: collection_name,
|
|
109
|
-
filter_keys: Object.keys(filter || {})
|
|
110
|
-
}
|
|
222
|
+
operation_metadata
|
|
111
223
|
);
|
|
112
224
|
};
|
|
113
225
|
|