]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2001,2003,2011,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | // | |
20 | // AppleDatabase.h - Description t.b.d. | |
21 | // | |
22 | #ifndef _H_APPLEDATABASE | |
23 | #define _H_APPLEDATABASE | |
24 | ||
25 | #include "MetaRecord.h" | |
26 | #include "SelectionPredicate.h" | |
27 | #include "DbIndex.h" | |
28 | ||
29 | #include <security_filedb/AtomicFile.h> | |
30 | #include <security_cdsa_plugin/Database.h> | |
31 | #include <security_cdsa_plugin/DbContext.h> | |
32 | #include <security_cdsa_utilities/handleobject.h> | |
33 | #include <security_utilities/refcount.h> | |
34 | #include <memory> | |
35 | #include <vector> | |
36 | #include <CoreFoundation/CFDate.h> | |
37 | ||
38 | namespace Security | |
39 | { | |
40 | ||
41 | // Abstract database Cursor class. | |
42 | class Cursor; | |
43 | class DbVersion; | |
44 | class CssmAutoQuery; | |
45 | ||
46 | struct AppleDatabaseTableName | |
47 | { | |
48 | uint32 mTableId; | |
49 | const char *mTableName; | |
50 | ||
51 | // indices of meta-table entries in an array of table names | |
52 | ||
53 | enum { | |
54 | kSchemaInfo = 0, | |
55 | kSchemaAttributes, | |
56 | kSchemaIndexes, | |
57 | kSchemaParsingModule, | |
58 | kNumRequiredTableNames | |
59 | }; | |
60 | }; | |
61 | ||
62 | // | |
63 | // This is what the CDSA standard refers to as a Relation. We use | |
64 | // the more conventional term Table. | |
65 | // | |
66 | class Table | |
67 | { | |
68 | NOCOPY(Table) | |
69 | public: | |
70 | // Type used to refer to a table. | |
71 | typedef CSSM_DB_RECORDTYPE Id; | |
72 | ||
73 | Table(const ReadSection &inTableSection); | |
74 | ~Table(); | |
75 | ||
76 | // Return a newly created cursor satisfying inQuery on the receiving table | |
77 | // The returned Cursor may or may not use indexes depending on their availability. | |
78 | Cursor *createCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion) const; | |
79 | ||
80 | const ReadSection getRecordSection(uint32 inRecordNumber) const; | |
81 | ||
82 | const RecordId getRecord(const RecordId &inRecordId, | |
83 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
84 | CssmData *inoutData, | |
85 | Allocator &inAllocator) const; | |
86 | ||
87 | // Return the number of recordNumbers in use by this table including empty slots. | |
88 | uint32 recordNumberCount() const { return mRecordNumbersCount; } | |
89 | uint32 freeListHead() const { return mFreeListHead; } | |
90 | ||
91 | // Return the record number corresponding to aFreeListHead and update | |
92 | // aFreeListHead to point to the next availble recordNumber slot. | |
93 | uint32 popFreeList(uint32 &aFreeListHead) const; | |
94 | ||
95 | MetaRecord &getMetaRecord() { return mMetaRecord; } | |
96 | const MetaRecord &getMetaRecord() const { return mMetaRecord; } | |
97 | ||
98 | uint32 getRecordsCount() const { return mRecordsCount; } | |
99 | const ReadSection getRecordsSection() const; | |
100 | ||
101 | const ReadSection &getTableSection() const { return mTableSection; } | |
102 | ||
103 | bool matchesTableId(Id inTableId) const; | |
104 | ||
105 | void readIndexSection(); | |
106 | ||
107 | enum | |
108 | { | |
109 | OffsetSize = AtomSize * 0, | |
110 | OffsetId = AtomSize * 1, | |
111 | OffsetRecordsCount = AtomSize * 2, | |
112 | OffsetRecords = AtomSize * 3, | |
113 | OffsetIndexesOffset = AtomSize * 4, | |
114 | OffsetFreeListHead = AtomSize * 5, | |
115 | OffsetRecordNumbersCount = AtomSize * 6, | |
116 | OffsetRecordNumbers = AtomSize * 7 | |
117 | }; | |
118 | protected: | |
119 | friend class ModifiedTable; | |
120 | ||
121 | MetaRecord mMetaRecord; | |
122 | const ReadSection mTableSection; | |
123 | ||
124 | uint32 mRecordsCount; | |
125 | uint32 mFreeListHead; | |
126 | // Number of record numbers (including freelist slots) in this table. | |
127 | uint32 mRecordNumbersCount; | |
128 | ||
129 | // all the table's indexes, mapped by index id | |
130 | typedef map<uint32, DbConstIndex *> ConstIndexMap; | |
131 | ConstIndexMap mIndexMap; | |
132 | }; | |
133 | ||
134 | class ModifiedTable | |
135 | { | |
136 | NOCOPY(ModifiedTable) | |
137 | public: | |
138 | ModifiedTable(const Table *inTable); | |
139 | ModifiedTable(MetaRecord *inMetaRecord); // Take over ownership of inMetaRecord | |
140 | ~ModifiedTable(); | |
141 | ||
142 | // Mark the record with inRecordId as deleted. | |
143 | void deleteRecord(const RecordId &inRecordId); | |
144 | const RecordId insertRecord(uint32 inVersionId, | |
145 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
146 | const CssmData *inData); | |
147 | const RecordId updateRecord(const RecordId &inRecordId, | |
148 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
149 | const CssmData *inData, | |
150 | CSSM_DB_MODIFY_MODE inModifyMode); | |
151 | const RecordId getRecord(const RecordId &inRecordId, | |
152 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
153 | CssmData *inoutData, | |
154 | Allocator &inAllocator) const; | |
155 | ||
156 | // Return the MetaRecord this table should use for writes. | |
157 | const MetaRecord &getMetaRecord() const; | |
158 | ||
159 | // find, and create if needed, an index with the given id | |
160 | DbMutableIndex &findIndex(uint32 indexId, const MetaRecord &metaRecord, bool isUniqueIndex); | |
161 | ||
162 | // Write this table to inOutputFile at inSectionOffset and return the new offset. | |
163 | uint32 writeTable(AtomicTempFile &inAtomicTempFile, uint32 inSectionOffset); | |
164 | ||
165 | private: | |
166 | // Return the next available record number for this table. | |
167 | uint32 nextRecordNumber(); | |
168 | ||
169 | // Return the number of recordNumbers in use by this table including empty slots. | |
170 | uint32 recordNumberCount() const; | |
171 | ||
172 | void modifyTable(); | |
173 | void createMutableIndexes(); | |
174 | uint32 writeIndexSection(WriteSection &tableSection, uint32 offset); | |
175 | ||
176 | // Optional, this is merly a reference, we do not own this object. | |
177 | const Table *mTable; | |
178 | ||
179 | // Optional, New MetaRecord. This is only present if it is different from the | |
180 | // MetaRecord of mTable or mTable is nil. | |
181 | const MetaRecord *mNewMetaRecord; | |
182 | ||
183 | // Set of Records that have been deleted or modified. | |
184 | typedef set<uint32> DeletedSet; | |
185 | DeletedSet mDeletedSet; | |
186 | ||
187 | // Set of Records that have been inserted or modified. | |
188 | typedef map<uint32, WriteSection *> InsertedMap; | |
189 | InsertedMap mInsertedMap; | |
190 | ||
191 | // Next lowest available RecordNumber | |
192 | uint32 mRecordNumberCount; | |
193 | // Head of the free list (if there is one) or 0 if either we have no | |
194 | // mTable of the free list has been exhausted. | |
195 | uint32 mFreeListHead; | |
196 | ||
197 | // has this table actually been modified? | |
198 | bool mIsModified; | |
199 | ||
200 | typedef map<uint32, DbMutableIndex *> MutableIndexMap; | |
201 | MutableIndexMap mIndexMap; | |
202 | }; | |
203 | ||
204 | // | |
205 | // Read only snapshot of a database. | |
206 | // | |
207 | class Metadata | |
208 | { | |
209 | NOCOPY(Metadata) | |
210 | protected: | |
211 | Metadata() {} | |
212 | enum | |
213 | { | |
214 | HeaderOffset = 0, // Absolute offset of header. | |
215 | OffsetMagic = AtomSize * 0, | |
216 | OffsetVersion = AtomSize * 1, | |
217 | OffsetAuthOffset = AtomSize * 2, | |
218 | OffsetSchemaOffset = AtomSize * 3, | |
219 | HeaderSize = AtomSize * 4, | |
220 | ||
221 | HeaderMagic = FOUR_CHAR_CODE('kych'), | |
222 | HeaderVersion = 0x00010000 | |
223 | }; | |
224 | ||
225 | enum | |
226 | { | |
227 | OffsetSchemaSize = AtomSize * 0, | |
228 | OffsetTablesCount = AtomSize * 1, | |
229 | OffsetTables = AtomSize * 2 | |
230 | }; | |
231 | }; | |
232 | ||
233 | // | |
234 | // Read only representation of a database | |
235 | // | |
236 | class DbVersion : public Metadata, public RefCount | |
237 | { | |
238 | NOCOPY(DbVersion) | |
239 | public: | |
240 | DbVersion(const class AppleDatabase &db, const RefPointer <AtomicBufferedFile> &inAtomicBufferedFile); | |
241 | ~DbVersion(); | |
242 | ||
243 | uint32 getVersionId() const { return mVersionId; } | |
244 | const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId, | |
245 | CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes, | |
246 | CssmData *inoutData, Allocator &inAllocator) const; | |
247 | Cursor *createCursor(const CSSM_QUERY *inQuery) const; | |
248 | protected: | |
249 | const Table &findTable(Table::Id inTableId) const; | |
250 | Table &findTable(Table::Id inTableId); | |
251 | ||
252 | private: | |
253 | void open(); // Part of constructor contract. | |
254 | ||
255 | ReadSection mDatabase; | |
256 | uint32 mVersionId; | |
257 | ||
258 | friend class DbModifier; // XXX Fixme | |
259 | typedef map<Table::Id, Table *> TableMap; | |
260 | TableMap mTableMap; | |
261 | const class AppleDatabase &mDb; | |
262 | RefPointer<AtomicBufferedFile> mBufferedFile; | |
263 | ||
264 | public: | |
265 | typedef Table value_type; | |
266 | typedef const Table &const_reference; | |
267 | typedef const Table *const_pointer; | |
268 | ||
269 | // A const forward iterator. | |
270 | class const_iterator | |
271 | { | |
272 | public: | |
273 | const_iterator(const TableMap::const_iterator &it) : mIterator(it) {} | |
274 | ||
275 | // Use default copy consturctor and assignment operator. | |
276 | //const_iterator(const const_iterator &it) : mIterator(it.mIterator) {} | |
277 | //const_iterator &operator=(const const_iterator &it) { mIterator = it.mIterator; return *this; } | |
278 | const_reference operator*() const { return *mIterator->second; } | |
279 | const_iterator &operator++() { mIterator.operator++(); return *this; } | |
280 | const_iterator operator++(int i) { return const_iterator(mIterator.operator++(i)); } | |
281 | bool operator!=(const const_iterator &other) const { return mIterator != other.mIterator; } | |
282 | bool operator==(const const_iterator &other) const { return mIterator == other.mIterator; } | |
283 | ||
284 | const_pointer operator->() const { return mIterator->second; } // Not really needed. | |
285 | ||
286 | private: | |
287 | TableMap::const_iterator mIterator; | |
288 | }; | |
289 | ||
290 | const_iterator begin() const { return const_iterator(mTableMap.begin()); } | |
291 | const_iterator end() const { return const_iterator(mTableMap.end()); } | |
292 | ||
293 | bool hasTable(Table::Id inTableId) const; | |
294 | }; | |
295 | ||
296 | // | |
297 | // Cursor | |
298 | // | |
299 | class Cursor : public HandleObject | |
300 | { | |
301 | public: | |
302 | Cursor(); | |
303 | Cursor(const DbVersion &inDbVersion); | |
304 | virtual ~Cursor(); | |
305 | virtual bool next(Table::Id &outTableId, | |
306 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, | |
307 | CssmData *outData, | |
308 | Allocator &inAllocator, | |
309 | RecordId &recordId); | |
310 | protected: | |
311 | const RefPointer<const DbVersion> mDbVersion; | |
312 | }; | |
313 | ||
314 | ||
315 | // | |
316 | // LinearCursor | |
317 | // | |
318 | class LinearCursor : public Cursor | |
319 | { | |
320 | NOCOPY(LinearCursor) | |
321 | public: | |
322 | LinearCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion, | |
323 | const Table &inTable); | |
324 | virtual ~LinearCursor(); | |
325 | virtual bool next(Table::Id &outTableId, | |
326 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, | |
327 | CssmData *outData, | |
328 | Allocator &inAllocator, | |
329 | RecordId &recordId); | |
330 | ||
331 | private: | |
332 | uint32 mRecordsCount; | |
333 | uint32 mRecord; | |
334 | const ReadSection mRecordsSection; | |
335 | uint32 mReadOffset; | |
336 | const MetaRecord &mMetaRecord; | |
337 | ||
338 | CSSM_DB_CONJUNCTIVE mConjunctive; | |
339 | CSSM_QUERY_FLAGS mQueryFlags; // If CSSM_QUERY_RETURN_DATA is set return the raw key bits; | |
340 | typedef vector<SelectionPredicate *> PredicateVector; | |
341 | ||
342 | PredicateVector mPredicates; | |
343 | }; | |
344 | ||
345 | // | |
346 | // A cursor that uses an index. | |
347 | // | |
348 | ||
349 | class IndexCursor : public Cursor | |
350 | { | |
351 | NOCOPY(IndexCursor) | |
352 | public: | |
353 | IndexCursor(DbQueryKey *queryKey, const DbVersion &inDbVersion, | |
354 | const Table &table, const DbConstIndex *index); | |
355 | virtual ~IndexCursor(); | |
356 | ||
357 | virtual bool next(Table::Id &outTableId, | |
358 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, | |
359 | CssmData *outData, | |
360 | Allocator &inAllocator, | |
361 | RecordId &recordId); | |
362 | ||
363 | private: | |
364 | auto_ptr<DbQueryKey> mQueryKey; | |
365 | const Table &mTable; | |
366 | const DbConstIndex *mIndex; | |
367 | ||
368 | DbIndexIterator mBegin, mEnd; | |
369 | }; | |
370 | ||
371 | // | |
372 | // MultiCursor | |
373 | // | |
374 | class MultiCursor : public Cursor | |
375 | { | |
376 | NOCOPY(MultiCursor) | |
377 | public: | |
378 | MultiCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion); | |
379 | virtual ~MultiCursor(); | |
380 | virtual bool next(Table::Id &outTableId, | |
381 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, | |
382 | CssmData *outData, | |
383 | Allocator &inAllocator, | |
384 | RecordId &recordId); | |
385 | private: | |
386 | auto_ptr<CssmAutoQuery> mQuery; | |
387 | ||
388 | DbVersion::const_iterator mTableIterator; | |
389 | auto_ptr<Cursor> mCursor; | |
390 | }; | |
391 | ||
392 | // | |
393 | // A DbModifier contains all pending changes to be made to a DB. | |
394 | // It also contains a DbVersion representing the state of the Database before any such changes | |
395 | // No read-style operations are supported by DbModifier. If a DbModifier exists for a | |
396 | // particular Database and a client wishes to perform a query commit() must be called and | |
397 | // the client should perform the new query on the current database version after the commit. | |
398 | // Otherwise a client will not see changes made since the DbModifier was instanciated. | |
399 | // | |
400 | class DbModifier : public Metadata | |
401 | { | |
402 | NOCOPY(DbModifier) | |
403 | public: | |
404 | DbModifier(AtomicFile &inAtomicFile, const class AppleDatabase &db); | |
405 | ~DbModifier(); | |
406 | ||
407 | // Whole database affecting members. | |
408 | void createDatabase(const CSSM_DBINFO &inDbInfo, | |
409 | const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry, | |
410 | mode_t mode); | |
411 | void openDatabase(); // This is optional right now. | |
412 | void closeDatabase(); | |
413 | void deleteDatabase(); | |
414 | ||
415 | void commit(); | |
416 | void rollback() throw(); | |
417 | ||
418 | // Record changing members | |
419 | void deleteRecord(Table::Id inTableId, const RecordId &inRecordId); | |
420 | const RecordId insertRecord(Table::Id inTableId, | |
421 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
422 | const CssmData *inData); | |
423 | const RecordId updateRecord(Table::Id inTableId, const RecordId &inRecordId, | |
424 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
425 | const CssmData *inData, | |
426 | CSSM_DB_MODIFY_MODE inModifyMode); | |
427 | ||
428 | // Schema changing members | |
429 | void insertTable(Table::Id inTableId, const string &inTableName, | |
430 | uint32 inNumberOfAttributes, | |
431 | const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, | |
432 | uint32 inNumberOfIndexes, | |
433 | const CSSM_DB_SCHEMA_INDEX_INFO *inIndexInfo); | |
434 | void deleteTable(Table::Id inTableId); | |
435 | ||
436 | // Record reading members | |
437 | const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId, | |
438 | CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes, | |
439 | CssmData *inoutData, Allocator &inAllocator); | |
440 | Cursor *createCursor(const CSSM_QUERY *inQuery); | |
441 | ||
442 | bool hasTable(Table::Id inTableid); | |
443 | ||
b1ab9ed8 | 444 | void modifyDatabase(); |
e3d460c9 | 445 | protected: |
b1ab9ed8 A |
446 | const RefPointer<const DbVersion> getDbVersion(bool force); |
447 | ||
448 | ModifiedTable *createTable(MetaRecord *inMetaRecord); // Takes over ownership of inMetaRecord | |
449 | ||
450 | void insertTableSchema(const CssmDbRecordAttributeInfo &inInfo, | |
451 | const CSSM_DB_RECORD_INDEX_INFO *inIndexInfo = NULL); | |
452 | ||
453 | void insertTable(const CssmDbRecordAttributeInfo &inInfo, | |
454 | const CSSM_DB_RECORD_INDEX_INFO * inIndexInfo = NULL, | |
455 | const CSSM_DB_PARSING_MODULE_INFO * inParsingModule = NULL); | |
456 | ||
457 | ModifiedTable &findTable(Table::Id inTableId); | |
458 | ||
459 | uint32 writeAuthSection(uint32 inSectionOffset); | |
460 | uint32 writeSchemaSection(uint32 inSectionOffset); | |
461 | ||
462 | private: | |
463 | ||
464 | /* mDbVersion is the current DbVersion of this database before any changes | |
465 | we are going to make. mNotifyCount holds the value of gNotifyCount at | |
466 | the time mDbVersion was created. mDbLastRead is the time at which we | |
467 | last checked if the file from which mDbVersion was read has changed. | |
468 | mDbVersionLock protects the other 3 fields. */ | |
469 | RefPointer<const DbVersion> mDbVersion; | |
470 | int32_t mNotifyCount; | |
471 | CFAbsoluteTime mDbLastRead; | |
472 | Mutex mDbVersionLock; | |
473 | ||
474 | AtomicFile &mAtomicFile; | |
475 | uint32 mVersionId; | |
476 | RefPointer<AtomicTempFile> mAtomicTempFile; | |
477 | ||
478 | typedef map<Table::Id, ModifiedTable *> ModifiedTableMap; | |
479 | ModifiedTableMap mModifiedTableMap; | |
480 | ||
481 | const class AppleDatabase &mDb; | |
482 | }; | |
483 | ||
484 | // | |
485 | // AppleDatabaseManager | |
486 | // | |
487 | class AppleDatabaseManager : public DatabaseManager | |
488 | { | |
489 | public: | |
490 | AppleDatabaseManager(const AppleDatabaseTableName *tableNames); | |
491 | Database *make(const DbName &inDbName); | |
492 | ||
493 | protected: | |
494 | const AppleDatabaseTableName *mTableNames; | |
495 | }; | |
496 | ||
497 | // | |
498 | // AppleDbContext | |
499 | // | |
500 | class AppleDbContext : public DbContext | |
501 | { | |
502 | public: | |
503 | AppleDbContext(Database &inDatabase, | |
504 | DatabaseSession &inDatabaseSession, | |
505 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
506 | const AccessCredentials *inAccessCred, | |
507 | const void *inOpenParameters); | |
508 | virtual ~AppleDbContext(); | |
509 | bool autoCommit() const { return mAutoCommit; } | |
510 | void autoCommit(bool on) { mAutoCommit = on; } | |
511 | mode_t mode() const { return mMode; } | |
512 | ||
513 | private: | |
514 | bool mAutoCommit; | |
515 | mode_t mMode; | |
516 | }; | |
517 | ||
518 | // | |
519 | // AppleDatabase | |
520 | // | |
521 | class AppleDatabase : public Database | |
522 | { | |
523 | public: | |
524 | AppleDatabase(const DbName &inDbName, const AppleDatabaseTableName *tableNames); | |
525 | virtual ~AppleDatabase(); | |
526 | ||
527 | virtual void | |
528 | dbCreate(DbContext &inDbContext, const CSSM_DBINFO &inDBInfo, | |
529 | const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry); | |
530 | ||
531 | virtual void | |
532 | dbOpen(DbContext &inDbContext); | |
533 | ||
534 | virtual void | |
535 | dbClose(); | |
536 | ||
537 | virtual void | |
538 | dbDelete(DatabaseSession &inDatabaseSession, | |
539 | const AccessCredentials *inAccessCred); | |
540 | ||
541 | virtual void | |
542 | createRelation(DbContext &inDbContext, | |
543 | CSSM_DB_RECORDTYPE inRelationID, | |
544 | const char *inRelationName, | |
545 | uint32 inNumberOfAttributes, | |
546 | const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, | |
547 | uint32 inNumberOfIndexes, | |
548 | const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo); | |
549 | ||
550 | virtual void | |
551 | destroyRelation(DbContext &inDbContext, | |
552 | CSSM_DB_RECORDTYPE inRelationID); | |
553 | ||
554 | virtual void | |
555 | authenticate(DbContext &inDbContext, | |
556 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
557 | const AccessCredentials &inAccessCred); | |
558 | ||
559 | virtual void | |
560 | getDbAcl(DbContext &inDbContext, | |
561 | const CSSM_STRING *inSelectionTag, | |
562 | uint32 &outNumberOfAclInfos, | |
563 | CSSM_ACL_ENTRY_INFO_PTR &outAclInfos); | |
564 | ||
565 | virtual void | |
566 | changeDbAcl(DbContext &inDbContext, | |
567 | const AccessCredentials &inAccessCred, | |
568 | const CSSM_ACL_EDIT &inAclEdit); | |
569 | ||
570 | virtual void | |
571 | getDbOwner(DbContext &inDbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner); | |
572 | ||
573 | virtual void | |
574 | changeDbOwner(DbContext &inDbContext, | |
575 | const AccessCredentials &inAccessCred, | |
576 | const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner); | |
577 | ||
578 | virtual char * | |
579 | getDbNameFromHandle(const DbContext &inDbContext) const; | |
580 | ||
581 | virtual CSSM_DB_UNIQUE_RECORD_PTR | |
582 | dataInsert(DbContext &inDbContext, | |
583 | CSSM_DB_RECORDTYPE RecordType, | |
584 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
585 | const CssmData *inData); | |
586 | ||
587 | virtual void | |
588 | dataDelete(DbContext &inDbContext, | |
589 | const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier); | |
590 | ||
591 | virtual void | |
592 | dataModify(DbContext &inDbContext, | |
593 | CSSM_DB_RECORDTYPE inRecordType, | |
594 | CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier, | |
595 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified, | |
596 | const CssmData *inDataToBeModified, | |
597 | CSSM_DB_MODIFY_MODE inModifyMode); | |
598 | ||
599 | virtual CSSM_HANDLE | |
600 | dataGetFirst(DbContext &inDbContext, | |
601 | const CssmQuery *inQuery, | |
602 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
603 | CssmData *inoutData, | |
604 | CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord); | |
605 | ||
606 | virtual bool | |
607 | dataGetNext(DbContext &inDbContext, | |
608 | CSSM_HANDLE inResultsHandle, | |
609 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
610 | CssmData *inoutData, | |
611 | CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord); | |
612 | ||
613 | virtual void | |
614 | dataAbortQuery(DbContext &inDbContext, | |
615 | CSSM_HANDLE inResultsHandle); | |
616 | ||
617 | virtual void | |
618 | dataGetFromUniqueRecordId(DbContext &inDbContext, | |
619 | const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, | |
620 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
621 | CssmData *inoutData); | |
622 | ||
623 | virtual void | |
624 | freeUniqueRecord(DbContext &inDbContext, | |
625 | CSSM_DB_UNIQUE_RECORD &inUniqueRecord); | |
626 | ||
627 | virtual void passThrough(DbContext &dbContext, | |
628 | uint32 passThroughId, | |
629 | const void *inputParams, | |
630 | void **outputParams); | |
631 | ||
632 | // Subclasses must implement this method. | |
633 | virtual DbContext *makeDbContext(DatabaseSession &inDatabaseSession, | |
634 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
635 | const AccessCredentials *inAccessCred, | |
636 | const void *inOpenParameters); | |
e3d460c9 | 637 | |
fa7225c8 | 638 | // These two methods will throw an exception on error |
e3d460c9 | 639 | virtual void dbMakeBackup(); |
fa7225c8 A |
640 | virtual void dbMakeCopy(const char * path); |
641 | ||
642 | // Delete the file under this database | |
643 | virtual void dbDeleteFile(); | |
e3d460c9 | 644 | |
b1ab9ed8 A |
645 | const CssmDbRecordAttributeInfo schemaRelations; |
646 | const CssmDbRecordAttributeInfo schemaAttributes; | |
647 | const CssmDbRecordAttributeInfo schemaIndexes; | |
648 | const CssmDbRecordAttributeInfo schemaParsingModule; | |
649 | ||
650 | const char *recordName(CSSM_DB_RECORDTYPE inRecordType) const; | |
651 | ||
652 | private: | |
653 | static void | |
654 | updateUniqueRecord(DbContext &inDbContext, | |
655 | CSSM_DB_RECORDTYPE inTableId, | |
656 | const RecordId &inRecordId, | |
657 | CSSM_DB_UNIQUE_RECORD &inoutUniqueRecord); | |
658 | ||
659 | CSSM_DB_UNIQUE_RECORD_PTR | |
660 | createUniqueRecord(DbContext &inDbContext, CSSM_DB_RECORDTYPE inTableId, | |
661 | const RecordId &inRecordId); | |
662 | const RecordId parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, | |
663 | CSSM_DB_RECORDTYPE &outTableId); | |
664 | ||
665 | Mutex mWriteLock; | |
666 | AtomicFile mAtomicFile; | |
667 | DbModifier mDbModifier; | |
668 | const AppleDatabaseTableName *mTableNames; | |
669 | }; | |
670 | ||
671 | } // end namespace Security | |
672 | ||
673 | #endif //_H_APPLEDATABASE |