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