1/* 2 * Copyright (c) 2000-2004,2011,2014 Apple 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// mdsclient - friendly interface to CDSA MDS API 21// 22#include <security_cdsa_client/mdsclient.h> 23 24 25namespace Security { 26namespace CssmClient { 27 28 29// 30// DLAccess gets a virtual destructor just in case 31// 32DLAccess::~DLAccess() 33{ } 34 35 36// 37// Basic Record objects (abstract) 38// 39Record::Record(const char * const * names) 40 : CssmAutoData(Allocator::standard(Allocator::sensitive)) 41{ 42 addAttributes(names); 43} 44 45void Record::addAttributes(const char * const * name) 46{ 47 if (name) 48 while (*name) 49 mAttributes.add(CssmDbAttributeInfo(*name++)); 50} 51 52Record::~Record() 53{ } 54 55 56// 57// Tables and their components (non-template common features) 58// 59TableBase::TableBase(DLAccess &source, CSSM_DB_RECORDTYPE type, bool getData /* = true */) 60 : database(source), mRecordType(type), mGetData(getData) 61{ 62} 63 64TableBase::Handle::~Handle() 65{ 66 if (query) 67 mAccess->dlAbortQuery(query); 68} 69 70TableBase::Uid::~Uid() 71{ 72 if (uid) 73 mAccess->dlFreeUniqueId(uid); 74} 75 76TableBase::Iterator::Iterator(DLAccess *ac, CSSM_HANDLE query, 77 CSSM_DB_UNIQUE_RECORD *id, Record *record, bool getData) 78 : mAccess(ac), mQuery(new Handle(ac, query)), 79 mUid(new Uid(ac, id)), mRecord(record), mGetData(getData) 80{ } 81 82 83void TableBase::Iterator::advance(Record *fill) 84{ 85 RefPointer<Record> newRecord = fill; // hold it safely 86 CSSM_DB_UNIQUE_RECORD *id; 87 CssmAutoData data(mAccess->allocator()); 88 if (mAccess->dlGetNext(mQuery->query, newRecord->attributes(), 89 mGetData ? &data.get() : NULL, id)) { 90 if (mGetData) 91 newRecord->recordData() = data; 92 mUid = new Uid(mAccess, id); 93 mRecord = newRecord; 94 } else { 95 mQuery->query = CSSM_INVALID_HANDLE; // was automatically aborted 96 // release all iterator resources and make me == end() 97 mQuery = NULL; 98 mUid = NULL; 99 mRecord = NULL; 100 } 101} 102 103 104uint32 TableBase::erase(const CSSM_QUERY &query) 105{ 106 CSSM_DB_UNIQUE_RECORD *id; 107 CssmDbRecordAttributeData noAttributes; 108 CSSM_HANDLE handle = database.dlGetFirst(query, noAttributes, NULL, id); 109 if (handle == CSSM_INVALID_HANDLE) 110 return 0; // no match, nothing erased 111 uint32 count = 0; 112 do { 113 database.dlDeleteRecord(id); 114 count++; 115 database.dlFreeUniqueId(id); 116 } while (database.dlGetNext(handle, noAttributes, NULL, id)); 117 return count; 118} 119 120uint32 TableBase::erase(const Query &query) 121{ 122 return erase(query.cssmQuery()); 123} 124 125 126} // end namespace CssmClient 127} // end namespace Security 128