/ OSX / libsecurity_cdsa_client / lib / dliterators.cpp
dliterators.cpp
  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  
 25  namespace Security {
 26  namespace CssmClient {
 27  
 28  
 29  //
 30  // DLAccess gets a virtual destructor just in case
 31  //
 32  DLAccess::~DLAccess()
 33  { }
 34  
 35  
 36  //
 37  // Basic Record objects (abstract)
 38  //
 39  Record::Record(const char * const * names)
 40  	: CssmAutoData(Allocator::standard(Allocator::sensitive))
 41  {
 42  	addAttributes(names);
 43  }
 44  
 45  void Record::addAttributes(const char * const * name)
 46  {
 47  	if (name)
 48  		while (*name)
 49  			mAttributes.add(CssmDbAttributeInfo(*name++));
 50  }
 51  
 52  Record::~Record()
 53  { }
 54  
 55  
 56  //
 57  // Tables and their components (non-template common features)
 58  //
 59  TableBase::TableBase(DLAccess &source, CSSM_DB_RECORDTYPE type, bool getData /* = true */)
 60  	: database(source), mRecordType(type), mGetData(getData)
 61  {
 62  }
 63  
 64  TableBase::Handle::~Handle()
 65  {
 66  	if (query)
 67  		mAccess->dlAbortQuery(query);
 68  }
 69  
 70  TableBase::Uid::~Uid()
 71  {
 72  	if (uid)
 73  		mAccess->dlFreeUniqueId(uid);
 74  }
 75  
 76  TableBase::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  
 83  void 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  
104  uint32 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  
120  uint32 TableBase::erase(const Query &query)
121  {
122  	return erase(query.cssmQuery());
123  }
124  
125  
126  } // end namespace CssmClient
127  } // end namespace Security