/ keychain / ckks / CKKSIncomingQueueEntry.m
CKKSIncomingQueueEntry.m
  1  /*
  2   * Copyright (c) 2016 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  #if OCTAGON
 25  
 26  #include <AssertMacros.h>
 27  
 28  #import <Foundation/Foundation.h>
 29  
 30  #import "CKKSKeychainView.h"
 31  
 32  #include <utilities/SecDb.h>
 33  #include "keychain/securityd/SecDbItem.h"
 34  #include "keychain/securityd/SecItemSchema.h"
 35  
 36  #import <CloudKit/CloudKit.h>
 37  #import "CKKSIncomingQueueEntry.h"
 38  #import "CKKSItemEncrypter.h"
 39  #import "CKKSSIV.h"
 40  
 41  @implementation CKKSIncomingQueueEntry
 42  
 43  - (NSString*)description {
 44      return [NSString stringWithFormat: @"<%@(%@): %@ %@ (%@)>",
 45              NSStringFromClass([self class]),
 46              self.item.zoneID.zoneName,
 47              self.action,
 48              self.item.uuid,
 49              self.state];
 50  }
 51  
 52  - (instancetype) initWithCKKSItem:(CKKSItem*) item
 53                             action:(NSString*) action
 54                              state:(NSString*) state {
 55      if(self = [super init]) {
 56          _item = item;
 57          _action = action;
 58          _state = state;
 59      }
 60  
 61      return self;
 62  }
 63  
 64  #pragma mark - Property access to underlying CKKSItem
 65  
 66  -(NSString*)uuid {
 67      return self.item.uuid;
 68  }
 69  
 70  -(void)setUuid:(NSString *)uuid {
 71      self.item.uuid = uuid;
 72  }
 73  
 74  #pragma mark - Database Operations
 75  
 76  + (instancetype) fromDatabase: (NSString*) uuid zoneID:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error {
 77      return [self fromDatabaseWhere: @{@"UUID": CKKSNilToNSNull(uuid), @"ckzone":CKKSNilToNSNull(zoneID.zoneName)} error: error];
 78  }
 79  
 80  + (instancetype) tryFromDatabase: (NSString*) uuid zoneID:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error {
 81      return [self tryFromDatabaseWhere: @{@"UUID": CKKSNilToNSNull(uuid), @"ckzone":CKKSNilToNSNull(zoneID.zoneName)} error: error];
 82  }
 83  
 84  + (NSArray<CKKSIncomingQueueEntry*>*)fetch:(ssize_t)n
 85                              startingAtUUID:(NSString*)uuid
 86                                       state:(NSString*)state
 87                                      action:(NSString* _Nullable)action
 88                                      zoneID:(CKRecordZoneID*)zoneID
 89                                       error: (NSError * __autoreleasing *) error {
 90      NSMutableDictionary* whereDict = [@{@"state": CKKSNilToNSNull(state), @"ckzone":CKKSNilToNSNull(zoneID.zoneName)} mutableCopy];
 91      whereDict[@"action"] = action;
 92      if(uuid) {
 93          whereDict[@"UUID"] = [CKKSSQLWhereValue op:CKKSSQLWhereComparatorGreaterThan value:uuid];
 94      }
 95      return [self fetch:n
 96                   where:whereDict
 97                 orderBy:@[@"UUID"]
 98                   error:error];
 99  }
100  
101  
102  #pragma mark - CKKSSQLDatabaseObject methods
103  
104  + (NSString*)sqlTable {
105      return @"incomingqueue";
106  }
107  
108  + (NSArray<NSString*>*)sqlColumns {
109      return [[CKKSItem sqlColumns] arrayByAddingObjectsFromArray: @[@"action", @"state"]];
110  }
111  
112  - (NSDictionary<NSString*,NSString*>*)whereClauseToFindSelf {
113      return [self.item whereClauseToFindSelf];
114  }
115  
116  - (NSDictionary<NSString*,NSString*>*)sqlValues {
117      NSMutableDictionary* values = [[self.item sqlValues] mutableCopy];
118      values[@"action"] = self.action;
119      values[@"state"] = self.state;
120      return values;
121  }
122  
123  
124  + (instancetype)fromDatabaseRow:(NSDictionary<NSString *, CKKSSQLResult*>*) row {
125      return [[CKKSIncomingQueueEntry alloc] initWithCKKSItem: [CKKSItem fromDatabaseRow: row]
126                                                       action:row[@"action"].asString
127                                                        state:row[@"state"].asString];
128  }
129  
130  + (NSDictionary<NSString*,NSNumber*>*)countsByStateInZone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error {
131      NSMutableDictionary* results = [[NSMutableDictionary alloc] init];
132  
133      [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable]
134                                          where: @{@"ckzone": CKKSNilToNSNull(zoneID.zoneName)}
135                                        columns: @[@"state", @"count(rowid)"]
136                                        groupBy: @[@"state"]
137                                        orderBy:nil
138                                          limit: -1
139                                     processRow: ^(NSDictionary<NSString*, CKKSSQLResult*>* row) {
140                                         results[row[@"state"].asString] = row[@"count(rowid)"].asNSNumberInteger;
141                                     }
142                                          error: error];
143      return results;
144  }
145  
146  + (NSInteger)countByState:(CKKSItemState *)state zone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error {
147      __block NSInteger result = -1;
148  
149      [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable]
150                                          where: @{@"ckzone": CKKSNilToNSNull(zoneID.zoneName), @"state": state }
151                                        columns: @[@"count(*)"]
152                                        groupBy: nil
153                                        orderBy: nil
154                                          limit: -1
155                                     processRow: ^(NSDictionary<NSString*, CKKSSQLResult*>* row) {
156                                         result = row[@"count(*)"].asNSInteger;
157                                     }
158                                          error: error];
159      return result;
160  }
161  
162  @end
163  
164  #endif