@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
|
@@ -14,65 +14,175 @@ import create_logger from '../logger.js';
|
|
|
14
14
|
const { create_context_logger } = create_logger('insert_one');
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {string} database_name -
|
|
19
|
-
* @
|
|
20
|
-
* @param {Object} document - Document to insert
|
|
21
|
-
* @param {Object} [options={}] - Insert options
|
|
22
|
-
* @returns {Promise<Object>} Insert result with acknowledged and inserted_id
|
|
23
|
-
* @throws {Error} When database/collection name is missing, document is invalid, or document already exists
|
|
17
|
+
* Validates database name parameter.
|
|
18
|
+
* @param {string} database_name - Database name to validate
|
|
19
|
+
* @throws {Error} When database name is missing
|
|
24
20
|
*/
|
|
25
|
-
const
|
|
26
|
-
const log = create_context_logger();
|
|
27
|
-
|
|
21
|
+
const validate_database_name = (database_name) => {
|
|
28
22
|
if (!database_name) {
|
|
29
23
|
throw new Error('Database name is required');
|
|
30
24
|
}
|
|
31
|
-
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Validates collection name parameter.
|
|
29
|
+
* @param {string} collection_name - Collection name to validate
|
|
30
|
+
* @throws {Error} When collection name is missing
|
|
31
|
+
*/
|
|
32
|
+
const validate_collection_name = (collection_name) => {
|
|
32
33
|
if (!collection_name) {
|
|
33
34
|
throw new Error('Collection name is required');
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Validates document parameter.
|
|
40
|
+
* @param {Object} document - Document to validate
|
|
41
|
+
* @throws {Error} When document is invalid
|
|
42
|
+
*/
|
|
43
|
+
const validate_document = (document) => {
|
|
36
44
|
if (!document || typeof document !== 'object') {
|
|
37
45
|
throw new Error('Document must be a valid object');
|
|
38
46
|
}
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validates all insert operation parameters.
|
|
51
|
+
* @param {string} database_name - Database name
|
|
52
|
+
* @param {string} collection_name - Collection name
|
|
53
|
+
* @param {Object} document - Document to insert
|
|
54
|
+
*/
|
|
55
|
+
const validate_insert_parameters = (database_name, collection_name, document) => {
|
|
56
|
+
validate_database_name(database_name);
|
|
57
|
+
validate_collection_name(collection_name);
|
|
58
|
+
validate_document(document);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates current timestamp string.
|
|
63
|
+
* @returns {string} ISO timestamp string
|
|
64
|
+
*/
|
|
65
|
+
const create_current_timestamp = () => {
|
|
66
|
+
return new Date().toISOString();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Prepares document for insertion with ID and timestamps.
|
|
71
|
+
* @param {Object} document - Original document
|
|
72
|
+
* @returns {Object} Document prepared for insertion
|
|
73
|
+
*/
|
|
74
|
+
const prepare_document_for_insertion = (document) => {
|
|
41
75
|
const document_id = document._id || generate_document_id();
|
|
42
|
-
const
|
|
76
|
+
const current_timestamp = create_current_timestamp();
|
|
43
77
|
|
|
44
|
-
|
|
78
|
+
return {
|
|
45
79
|
...document,
|
|
46
80
|
_id: document_id,
|
|
47
|
-
_created_at:
|
|
48
|
-
_updated_at:
|
|
81
|
+
_created_at: current_timestamp,
|
|
82
|
+
_updated_at: current_timestamp
|
|
49
83
|
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Checks if document already exists in collection.
|
|
88
|
+
* @param {Object} db - Database instance
|
|
89
|
+
* @param {string} collection_key - Collection key for document
|
|
90
|
+
* @param {string} document_id - Document ID
|
|
91
|
+
* @throws {Error} When document already exists
|
|
92
|
+
*/
|
|
93
|
+
const check_document_does_not_exist = (db, collection_key, document_id) => {
|
|
94
|
+
const existing_document = db.get(collection_key);
|
|
50
95
|
|
|
51
|
-
|
|
96
|
+
if (existing_document) {
|
|
97
|
+
throw new Error(`Document with _id ${document_id} already exists`);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Stores document in database within transaction.
|
|
103
|
+
* @param {Object} db - Database instance
|
|
104
|
+
* @param {string} collection_key - Collection key for document
|
|
105
|
+
* @param {Object} document_to_insert - Document to store
|
|
106
|
+
* @returns {Object} The inserted document
|
|
107
|
+
* @throws {Error} When document already exists or transaction fails
|
|
108
|
+
*/
|
|
109
|
+
const store_document_in_transaction = (db, collection_key, document_to_insert) => {
|
|
110
|
+
// Check for duplicate before starting transaction
|
|
111
|
+
check_document_does_not_exist(db, collection_key, document_to_insert._id);
|
|
52
112
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
throw new Error(`Document with _id ${document_id} already exists`);
|
|
58
|
-
}
|
|
59
|
-
|
|
113
|
+
// Perform the insert within transaction
|
|
114
|
+
db.transaction(() => {
|
|
115
|
+
// Double-check within transaction to handle race conditions
|
|
116
|
+
check_document_does_not_exist(db, collection_key, document_to_insert._id);
|
|
60
117
|
db.put(collection_key, JSON.stringify(document_to_insert));
|
|
61
|
-
inserted_document = document_to_insert;
|
|
62
118
|
});
|
|
63
119
|
|
|
64
|
-
|
|
65
|
-
|
|
120
|
+
return document_to_insert;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Logs successful document insertion.
|
|
125
|
+
* @param {Function} log - Logger function
|
|
126
|
+
* @param {string} database_name - Database name
|
|
127
|
+
* @param {string} collection_name - Collection name
|
|
128
|
+
* @param {string} document_id - Document ID
|
|
129
|
+
*/
|
|
130
|
+
const log_successful_insertion = (log, database_name, collection_name, document_id) => {
|
|
66
131
|
log.info('Document inserted successfully', {
|
|
67
132
|
database: database_name,
|
|
68
133
|
collection: collection_name,
|
|
69
134
|
document_id: document_id
|
|
70
135
|
});
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Creates insert operation result.
|
|
140
|
+
* @param {string} document_id - ID of inserted document
|
|
141
|
+
* @returns {Object} Insert result object
|
|
142
|
+
*/
|
|
143
|
+
const create_insert_result = (document_id) => ({
|
|
144
|
+
acknowledged: true,
|
|
145
|
+
inserted_id: document_id
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Creates write queue operation metadata.
|
|
150
|
+
* @param {string} database_name - Database name
|
|
151
|
+
* @param {string} collection_name - Collection name
|
|
152
|
+
* @param {Object} document - Document being inserted
|
|
153
|
+
* @returns {Object} Operation metadata
|
|
154
|
+
*/
|
|
155
|
+
const create_write_queue_metadata = (database_name, collection_name, document) => ({
|
|
156
|
+
operation: 'insert_one',
|
|
157
|
+
database: database_name,
|
|
158
|
+
collection: collection_name,
|
|
159
|
+
document_id: document._id || 'auto-generated'
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Internal implementation of insert_one operation without write queue serialization.
|
|
164
|
+
* @param {string} database_name - Name of the database
|
|
165
|
+
* @param {string} collection_name - Name of the collection
|
|
166
|
+
* @param {Object} document - Document to insert
|
|
167
|
+
* @param {Object} options - Insert options
|
|
168
|
+
* @returns {Promise<Object>} Insert result with acknowledged and inserted_id
|
|
169
|
+
*/
|
|
170
|
+
const insert_one_internal = async (database_name, collection_name, document, options = {}) => {
|
|
171
|
+
const log = create_context_logger();
|
|
71
172
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
173
|
+
validate_insert_parameters(database_name, collection_name, document);
|
|
174
|
+
|
|
175
|
+
const db = get_database();
|
|
176
|
+
const document_to_insert = prepare_document_for_insertion(document);
|
|
177
|
+
const collection_key = build_collection_key(database_name, collection_name, document_to_insert._id);
|
|
178
|
+
|
|
179
|
+
const inserted_document = store_document_in_transaction(db, collection_key, document_to_insert);
|
|
180
|
+
|
|
181
|
+
await update_indexes_on_insert(database_name, collection_name, inserted_document);
|
|
182
|
+
|
|
183
|
+
log_successful_insertion(log, database_name, collection_name, document_to_insert._id);
|
|
184
|
+
|
|
185
|
+
return create_insert_result(document_to_insert._id);
|
|
76
186
|
};
|
|
77
187
|
|
|
78
188
|
/**
|
|
@@ -80,33 +190,18 @@ const insert_one_internal = async (database_name, collection_name, document, opt
|
|
|
80
190
|
* @param {string} database_name - Name of the database
|
|
81
191
|
* @param {string} collection_name - Name of the collection
|
|
82
192
|
* @param {Object} document - Document to insert
|
|
83
|
-
* @param {Object}
|
|
193
|
+
* @param {Object} options - Insert options
|
|
84
194
|
* @returns {Promise<Object>} Insert result with acknowledged and inserted_id
|
|
85
|
-
* @throws {Error} When database/collection name is missing or document is invalid
|
|
86
195
|
*/
|
|
87
196
|
const insert_one = async (database_name, collection_name, document, options = {}) => {
|
|
88
|
-
|
|
89
|
-
throw new Error('Database name is required');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!collection_name) {
|
|
93
|
-
throw new Error('Collection name is required');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (!document || typeof document !== 'object') {
|
|
97
|
-
throw new Error('Document must be a valid object');
|
|
98
|
-
}
|
|
197
|
+
validate_insert_parameters(database_name, collection_name, document);
|
|
99
198
|
|
|
100
199
|
const write_queue = get_write_queue();
|
|
200
|
+
const operation_metadata = create_write_queue_metadata(database_name, collection_name, document);
|
|
101
201
|
|
|
102
202
|
return await write_queue.enqueue_write_operation(
|
|
103
203
|
() => insert_one_internal(database_name, collection_name, document, options),
|
|
104
|
-
|
|
105
|
-
operation: 'insert_one',
|
|
106
|
-
database: database_name,
|
|
107
|
-
collection: collection_name,
|
|
108
|
-
document_id: document._id || 'auto-generated'
|
|
109
|
-
}
|
|
204
|
+
operation_metadata
|
|
110
205
|
);
|
|
111
206
|
};
|
|
112
207
|
|