PageRenderTime 54ms CodeModel.GetById 20ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMSQLite.h

http://macfuse.googlecode.com/
C++ Header | 713 lines | 93 code | 71 blank | 549 comment | 0 complexity | 75ff73b1368ae1359a679c6a9cd1bf81 MD5 | raw file
  1//
  2//  GTMSQLite.h
  3//
  4//  Copyright 2006-2008 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9//
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11//
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18//
 19//  This class is a convenience wrapper for SQLite storage with
 20//  release/retain semantics. In its most basic form, that is all this
 21//  class offers. You have the option of activating "CFAdditions" on
 22//  init which patches or overrides the following SQLite functionality:
 23//
 24//  - Strings you pass through the API layer will always be converted
 25//  to precomposed UTF-8 with compatibility mapping
 26//  (kCFStringNormalizationFormKC).  This is done in an attempt to
 27//  make SQLite correctly handle string equality for composed
 28//  character sequences. This change applies only to
 29//  NSStrings/CFStrings passed through the GTMSQLiteDatabase or
 30//  GTMSQLiteStatement. Direct access to the database using the
 31//  underlying sqlite3_* handles is not affected.
 32//
 33//  - The SQL UPPER/LOWER functions are replaced with CFString-based
 34//  implementations which (unlike SQLite's native implementation)
 35//  handle case conversion outside the ASCII range. These
 36//  implementations seem to be 20-30% slower than the SQLite
 37//  implementations but may be worth it for accuracy.
 38//
 39//  - The SQLite "NOCASE" collation is replaced with a CFString-based
 40//  collation that is case insensitive but still uses literal
 41//  comparison (composition-sensitive).
 42//
 43//  - Additional collation sequences can be created by using these keywords
 44//  separated by underscores. Each option corresponds to a CFStringCompareFlags
 45//  option.
 46//    NOCASE                  (kCFCompareCaseInsensitive)
 47//    NONLITERAL              (kCFCompareNonliteral)
 48//    LOCALIZED               (kCFCompareLocalized)
 49//    NUMERIC                 (kCFCompareNumerically)
 50
 51//  These additional options are available when linking with the 10.5 SDK:
 52//    NODIACRITIC             (kCFCompareDiacriticInsensitive)
 53//    WIDTHINSENSITIVE        (kCFCompareWidthInsensitive)
 54//
 55//  Ordering of the above options can be changed by adding "REVERSE".
 56//
 57//  Thus, for a case-insensitive, width-insensitive, composition-insensitive
 58//  comparison that ignores diacritical marks and sorts in reverse use:
 59//
 60//    NOCASE_NONLITERAL_NODIACRITIC_WIDTHINSENSITIVE_REVERSE
 61//
 62//  - SQL LIKE and GLOB commands are implemented with CFString/CFCharacterSet
 63//  comparisons. As with the other CF additions, this gives us better handling
 64//  of case and composed character sequences. However, whereever reasonable,
 65//  SQLite semantics have been retained. Specific notes:
 66//
 67//    * LIKE is case insensitive and uses non-literal comparison
 68//      (kCFCompareNonliteral) by default. It is possible to modify this
 69//      behavior using the accessor methods. You must use those methods
 70//      instead of the SQLite  "PRAGMA case_sensitive_like" in order for them
 71//      to interact properly with our CFString implementations.
 72//
 73//    * ESCAPE clauses to LIKE are honored, but the escape character must
 74//      be expressable as a single UniChar (UTF16). The escaped characters in
 75//      LIKE only escape the following UniChar, not a composed character
 76//      sequence. This is not viewed as a limitation since the use of ESCAPE
 77//      is typically only for characters with meaning to SQL LIKE ('%', '_')
 78//      all of which can be expressed as a single UniChar.
 79//
 80//    * GLOB is by default case sensitive but non-literal. Again, accessor
 81//      methods are available to change this behavior.
 82//
 83//    * Single character pattern matches ('_' for LIKE, '?' for GLOB) will
 84//      always consume a full composed character sequence.
 85//
 86//    * As with the standard SQLite implementation, character set comparisons
 87//      are only available for GLOB.
 88//
 89//    * Character set comparisons are always literal and case sensitive and do
 90//      not take into account composed character sequences. Essentially
 91//      character sets should always be expressed as a set of single UniChars
 92//      or ranges between single UniChars.
 93//
 94
 95//  SQLite is preinstalled on 10.4 only. As long as we're using the OS version
 96//  of the library, limit ourself to Tiger+
 97#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
 98#error SQLite support is Tiger or later
 99#endif
100
101#import <Foundation/Foundation.h>
102#import <sqlite3.h>
103
104/// Wrapper for SQLite with release/retain semantics and CFString convenience features
105@interface GTMSQLiteDatabase : NSObject {
106 @protected
107  sqlite3 *db_;     // strong
108  NSString *path_;   // strong
109  int timeoutMS_;
110  BOOL hasCFAdditions_;
111  CFOptionFlags likeOptions_;
112  CFOptionFlags globOptions_;
113  NSMutableArray *userArgDataPool_;  // strong
114}
115
116//  Get the numeric version number of the SQLite library (compiled in value
117//  for SQLITE_VERSION_NUMBER).
118//
119//  Returns:
120//    Integer version number
121//
122+ (int)sqliteVersionNumber;
123
124//  Get the string version number of the SQLite library.
125//
126//  Returns:
127//    Autoreleased NSString version string
128//
129+ (NSString *)sqliteVersionString;
130
131//  Create and open a database instance on a file-based database.
132//
133//  Args:
134//    path: Path to the database. If it does not exist an empty database
135//          will be created.
136//    withCFAdditions: If true, the SQLite database will include CFString
137//                     based string functions and collation sequences. See
138//                     the class header for information on these differences
139//                     and performance impact.
140//    err:  Result code from SQLite. If nil is returned by this function
141//          check the result code for the error. If NULL no result code is
142//          reported.
143//
144- (id)initWithPath:(NSString *)path
145   withCFAdditions:(BOOL)additions
146              utf8:(BOOL)useUTF8
147         errorCode:(int *)err;
148
149//  Create and open a memory-based database. Memory-based databases
150//  cannot be shared amongst threads, and each instance is unique. See
151//  SQLite documentation for details.
152//
153//  For argument details see [... initWithPath:withCFAdditions:errorCode:]
154//
155- (id)initInMemoryWithCFAdditions:(BOOL)additions
156                             utf8:(BOOL)useUTF8
157                        errorCode:(int *)err;
158
159//  Get the underlying SQLite database handle. In general you should
160//  never do this, if you do use this be careful with how you compose
161//  and decompse strings you pass to the database.
162//
163//  Returns:
164//    sqlite3 pointer
165//
166- (sqlite3 *)sqlite3DB;
167
168//  Enable/Disable the database synchronous mode. Disabling
169//  synchronous mode results in much faster insert throughput at the
170//  cost of safety. See the SQlite documentation for details.
171//
172//  Args:
173//    enable: Boolean flag to determine mode.
174//
175- (void)synchronousMode:(BOOL)enable;
176
177//  Check if this database instance has our CFString functions and collation
178//  sequences (see top of file for details).
179//
180//  Returns:
181//    YES if the GTMSQLiteDatabase instance has our CF additions
182//
183- (BOOL)hasCFAdditions;
184
185//  Set comparison options for the "LIKE" operator for databases with
186//  our CF addtions active.
187//
188//  Args:
189//    options: CFStringCompareFlags value. Note that a limited list
190//             of options are supported. For example one cannot
191//             use kCFCompareBackwards as an option.
192//
193- (void)setLikeComparisonOptions:(CFOptionFlags)options;
194
195//  Get current comparison options for the "LIKE" operator in a database
196//  with our CF additions active.
197//
198//  Returns:
199//    Current comparison options or zero if CF additions are inactive.
200//
201- (CFOptionFlags)likeComparisonOptions;
202
203//  Set comparison options for the "GLOB" operator for databases with
204//  our CF addtions active.
205//
206//  Args:
207//    options: CFStringCompareFlags value. Note that a limited list
208//             of options are supported. For example one cannot
209//             use kCFCompareBackwards as an option.
210//
211- (void)setGlobComparisonOptions:(CFOptionFlags)options;
212
213//  Get current comparison options for the "GLOB" operator in a database
214//  with our CF additions active.
215//
216//  Returns:
217//    Current comparison options or zero if CF additions are inactive.
218//
219- (CFOptionFlags)globComparisonOptions;
220
221//  Obtain the last error code from the database
222//
223//  Returns:
224//    SQLite error code, if no error is pending returns SQLITE_OK
225//
226- (int)lastErrorCode;
227
228//  Obtain an error string for the last error from the database
229//
230//  Returns:
231//    Autoreleased NSString error message
232//
233- (NSString *)lastErrorString;
234
235//  Obtain a count of rows added, mmodified or deleted by the most recent
236//  statement. See sqlite3_changes() for details and limitations.
237//
238//  Returns:
239//    Row count
240//
241- (int)lastChangeCount;
242
243//  Obtain a count of rows added, mmodified or deleted since the database
244//  was opened. See sqlite3_total_changes() for details and limitations.
245//
246//  Returns:
247//    Row count
248//
249- (int)totalChangeCount;
250
251//  Obtain the last insert row ID
252//
253//  Returns:
254//    64-bit row ID
255//
256- (unsigned long long)lastInsertRowID;
257
258//  Interrupt any currently running database operations as soon as possible.
259//  Running operations will receive a SQLITE_INTERRUPT and will need to
260//  handle it correctly (this is the callers problem to deal with).
261//
262- (void)interrupt;
263
264//  Set the timeout value in milliseconds. This is a database global affecting
265//  all running and future statements.
266//
267//  Args:
268//    timeoutMS: Integer count in ms SQLite will wait for the database to
269//               unlock before giving up and returning SQLITE_BUSY. A value
270//               of 0 or less means the database always returns immediately.
271//
272//  Returns:
273//    SQLite result code, SQLITE_OK on no error
274//
275- (int)setBusyTimeoutMS:(int)timeoutMS;
276
277//  Get the current busy timeout in milliseconds.
278//
279//  Returns:
280//    Current database busy timeout value in ms, 0 or less means no timeout.
281//
282- (int)busyTimeoutMS;
283
284//  Execute a string containing one or more SQL statements. No returned data
285//  is available, use GTMSQLiteStatement for that usage.
286//
287//  Args:
288//    sql: Raw SQL statement to prepare. It is the caller's responsibility
289//         to properly escape the SQL.
290//
291//  Returns:
292//    SQLite result code, SQLITE_OK on no error
293//
294- (int)executeSQL:(NSString *)sql;
295
296//  Convenience method to start a deferred transaction (most common case).
297//
298//  Returns:
299//    YES if the transaction started successfully
300//
301- (BOOL)beginDeferredTransaction;
302
303//  Convenience method to roll back a transaction.
304//
305//  Returns:
306//    YES if the transaction rolled back successfully
307//
308- (BOOL)rollback;
309
310//  Convenience method to commit a transaction.
311//
312//  Returns:
313//    YES if the transaction committed successfully
314//
315- (BOOL)commit;
316
317@end
318
319//  Wrapper class for SQLite statements with retain/release semantics.
320//  Attempts to behave like an NSEnumerator, however you should bind
321//  your values before beginning enumeration and unlike NSEnumerator,
322//  a reset is supported.
323//
324//  The GTMSQLiteDatabase class has options to modify some SQL
325//  functions and force particular string representations. This class
326//  honors the database preferences for those options. See the
327//  GTMSQLiteDatabase header for details.
328
329///  Wrapper class for SQLite statements with retain/release
330///  semantics.
331@interface GTMSQLiteStatement : NSObject {
332
333@protected
334  sqlite3_stmt *statement_;
335  BOOL hasCFAdditions_;
336}
337
338#pragma mark Creation, Access and Finalization
339
340//  Create an autoreleased prepared statement, see initWithSQL: for arguments.
341//
342//  NOTE: Even though this object is autoreleased you MUST call
343//  [finalizeStatement] on this when your done. See the init for explanation.
344//
345//  Returns:
346//    Autoreleased GTMSQLiteStatement
347//
348+ (id)statementWithSQL:(NSString *)sql
349            inDatabase:(GTMSQLiteDatabase *)gtmdb
350             errorCode:(int *)err;
351
352//  Designated initializer, create a prepared statement. Positional and named
353//  parameters are supported, see the SQLite documentation.
354//
355//  NOTE: Although this object will clean up its statement when deallocated,
356//  you are REQUIRED to "finalize" the statement when you are
357//  through with it. Failing to do this will prevent the database from allowing
358//  new transactions or queries. In other words, leaving an instance on the
359//  autorelease pool unfinalized may interfere with other database usage if any
360//  caller sharing the database uses transactions.
361//
362//  Args:
363//    sql: Raw SQL statement to prepare. It is the caller's responsibility
364//         to properly escape the SQL and make sure that the SQL contains
365//         only _one_ statement. Additional statements are silently ignored.
366//    db: The GTMSQLiteDatabase (not retained)
367//    err:  Result code from SQLite. If nil is returned by this function
368//          check the result code for the error. If NULL no result code is
369//          reported.
370//
371- (id)initWithSQL:(NSString *)sql
372       inDatabase:(GTMSQLiteDatabase *)gtmdb
373        errorCode:(int *)err;
374
375//  Get the underlying SQLite statement handle. In general you should never
376//  do this, if you do use this be careful with how you compose and
377//  decompse strings you pass to the database.
378//
379//  Returns:
380//    sqlite3_stmt pointer
381//
382- (sqlite3_stmt *)sqlite3Statement;
383
384//  Finalize the statement, allowing other transactions to start on the database
385//  This method MUST be called when you are done with a statement.  Failure to
386//  do so means that the database will not be torn down properly when it's
387//  retain count drops to 0 or GC collects it.
388//
389//  Returns:
390//    SQLite result code, SQLITE_OK on no error
391//
392- (int)finalizeStatement;
393
394#pragma mark Parameters and Binding
395
396//  Get the number of parameters that can be bound in the prepared statement.
397//
398//  Returns:
399//    Integer count of parameters or -1 on error
400//
401- (int)parameterCount;
402
403//  Get the position of a parameter with a given name.
404//
405//  Args:
406//    paramName: String name of the parameter, including any leading punctuation
407//               (see SQLite docs)
408//
409//  Returns:
410//    1-based parameter position index or -1 on error
411//
412- (int)positionOfParameterNamed:(NSString *)paramName;
413
414//  Get the name of a parameter at a particular index.
415//
416//  Args:
417//    position: Parameter position (1-based index)
418//
419//  Returns:
420//    Autoreleased string name of the parameter, including any leading
421//    punctuation (see SQLite docs) or nil on error.
422//
423- (NSString *)nameOfParameterAtPosition:(int)position;
424
425//  Bind a NULL at a given position
426//
427//  Args:
428//    position: Parameter position (1-based index)
429//
430//  Returns:
431//    SQLite result code, SQLITE_OK on no error
432//
433- (int)bindSQLNullAtPosition:(int)position;
434
435//  Bind a blob parameter at a given position index to a raw pointer and
436//  length. The data will be copied by SQLite
437//
438//  Args:
439//    position: Parameter position (1-based index)
440//    bytes: Raw pointer to the data to copy/bind
441//    length: Number of bytes in the blob
442//
443//  Returns:
444//    SQLite result code, SQLITE_OK on no error
445//
446- (int)bindBlobAtPosition:(int)position bytes:(void *)bytes length:(int)length;
447
448//  Bind an NSData as a blob at a given position. The data will be copied
449//  by SQLite.
450//
451//  Args:
452//    position: Parameter position (1-based index)
453//    data: NSData to convert to blob
454//
455//  Returns:
456//    SQLite result code, SQLITE_OK on no error
457//
458- (int)bindBlobAtPosition:(int)position data:(NSData *)data;
459
460//  Bind a double at the given position (for floats convert to double).
461//
462//  Args:
463//    position: Parameter position (1-based index)
464//    value: Double to bind
465//
466//  Returns:
467//    SQLite result code, SQLITE_OK on no error
468//
469- (int)bindDoubleAtPosition:(int)position value:(double)value;
470
471//  Bind an NSNumber as a double value at the given position.
472//
473//  Args:
474//    position: Parameter position (1-based index)
475//    number: NSNumber to bind
476//
477//  Returns:
478//    SQLite result code, SQLITE_OK on no error
479//
480- (int)bindNumberAsDoubleAtPosition:(int)position number:(NSNumber *)number;
481
482//  Bind a 32-bit integer at the given position.
483//
484//  Args:
485//    position: Parameter position (1-based index)
486//    value: Integer to bind
487//
488//  Returns:
489//    SQLite result code, SQLITE_OK on no error
490//
491- (int)bindInt32AtPosition:(int)position value:(int)value;
492
493//  Bind an NSNumber as a 32-bit integer value at the given position.
494//
495//  Args:
496//    position: Parameter position (1-based index)
497//    number: NSNumber to bind
498//
499//  Returns:
500//    SQLite result code, SQLITE_OK on no error
501//
502- (int)bindNumberAsInt32AtPosition:(int)position number:(NSNumber *)number;
503
504//  Bind a 64-bit integer at the given position.
505//
506//  Args:
507//    position: Parameter position (1-based index)
508//    value: Int64 value to bind
509//
510//  Returns:
511//    SQLite result code, SQLITE_OK on no error
512//
513- (int)bindLongLongAtPosition:(int)position value:(long long)value;
514
515//  Bind an NSNumber as a 64-bit integer value at the given position.
516//
517//  Args:
518//    position: Parameter position (1-based index)
519//    number: NSNumber to bind
520//
521//  Returns:
522//    SQLite result code, SQLITE_OK on no error
523//
524- (int)bindNumberAsLongLongAtPosition:(int)position number:(NSNumber *)number;
525
526//  Bind a string at the given position.
527//
528//  Args:
529//    position: Parameter position (1-based index)
530//    string: String to bind (string will be converted to UTF8 and copied).
531//            NOTE: For bindings it is not necessary for you to SQL escape
532//                  your strings.
533//
534//  Returns:
535//    SQLite result code, SQLITE_OK on no error
536//
537- (int)bindStringAtPosition:(int)position string:(NSString *)string;
538
539#pragma mark Results
540
541//  Get the number of result columns per row this statement will generate.
542//
543//  Returns:
544//    Column count, 0 if no columns will be returned ("UPDATE.." etc.),
545//    -1 on error.
546//
547- (int)resultColumnCount;
548
549//  Get the name of result colument at a given index.
550//
551//  Args:
552//    position: Column position (0-based index)
553//
554//  Returns:
555//    Autoreleased NSString column name or nil if no column exists at that
556//    position or error.
557//
558- (NSString *)resultColumnNameAtPosition:(int)position;
559
560//  Get the number of data values in the current row of this statement.
561//  Generally this will be the same as resultColumnCount:, except when row
562//  iteration is done (see SQLite docs for sqlite3_data_count()).
563//
564//  Returns:
565//    Data count or 0 if no data will be returned, -1 on error.
566//
567- (int)rowDataCount;
568
569//  Get the SQLite type constant for a column in a row. Note that because
570//  SQLite does not enforce column type restrictions the type of a particular
571//  column in a row may not match the declared type of the column.
572//
573//  Args:
574//    position: Column position (0-based index)
575//
576//  Returns:
577//    SQLite data type constant (i.e. SQLITE_INTEGER, SQLITE_FLOAT, etc.) or
578//    -1 on error.
579//
580- (int)resultColumnTypeAtPosition:(int)position;
581
582//  Get the data for a result row blob column as an NSData
583//
584//  Args:
585//    position: Column position (0-based index)
586//
587//  Returns:
588//    Autoreleased NSData, nil on error
589//
590- (NSData *)resultBlobDataAtPosition:(int)position;
591
592//  Get the data for a result row blob column as a double
593//
594//  Args:
595//    position: Column position (0-based index)
596//
597//  Returns:
598//    Double value
599//
600- (double)resultDoubleAtPosition:(int)position;
601
602//  Get the data for a result row blob column as an integer
603//
604//  Args:
605//    position: Column position (0-based index)
606//
607//  Returns:
608//    Integer value
609//
610- (int)resultInt32AtPosition:(int)position;
611
612//  Get the data for a result row blob column as a long long
613//
614//  Args:
615//    position: Column position (0-based index)
616//
617//  Returns:
618//    Long long value
619//
620- (long long)resultLongLongAtPosition:(int)position;
621
622//  Get the data for a result row blob column as an NSNumber
623//
624//  Args:
625//    position: Column position (0-based index)
626//
627//  Returns:
628//    Autoreleased NSNumber value or nil on error
629//
630- (NSNumber *)resultNumberAtPosition:(int)position;
631
632//  Get the data for a result row blob column as an NSString
633//
634//  Args:
635//    position: Column position (0-based index)
636//
637//  Returns:
638//    Autoreleased NSString value or nil on error
639//
640- (NSString *)resultStringAtPosition:(int)position;
641
642//  Get a Foundation object (NSData, NSNumber, NSString, NSNull) for the column,
643//  autodetecting the most appropriate representation.
644//
645//  Args:
646//    position: Column position (0-based index)
647//
648//  Returns:
649//    Autoreleased Foundation type, nil on error
650//
651- (id)resultFoundationObjectAtPosition:(int)position;
652
653//  Get an array of Foundation objects for the row in query column order.
654//
655//  Returns:
656//    Autoreleased array of Foundation types or nil if there is no
657//    data in the row or error
658//
659- (NSArray *)resultRowArray;
660
661//  Get a dictionary of Foundation objects for the row keyed by column name.
662//
663//  Returns:
664//    Autoreleased dictionary of Foundation types or nil if there is no
665//    data in the row or error.
666//
667- (NSDictionary *)resultRowDictionary;
668
669#pragma mark Rows
670
671//  Step the statement forward one row, potentially spinning forever till
672//  the row can be located (if database is SQLITE_BUSY).
673//
674//  Returns:
675//    SQLite result code, SQLITE_ROW if a row was found or SQLITE_DONE if
676//    no further rows match the statement.
677//
678- (int)stepRow;
679
680//  Step the statement forward one row, waiting at most the currrent database
681//  busy timeout (see [GTMSQLiteDatabase setBusyTimeoutMS]).
682//
683//  Returns:
684//    SQLite result code, SQLITE_ROW if a row was found or SQLITE_DONE if
685//    no further rows match the statement. If SQLITE_BUSY is returned the
686//    database did not unlock during the timeout.
687//
688- (int)stepRowWithTimeout;
689
690//  Reset the statement starting again at the first row
691//
692//  Returns:
693//    SQLite result code, SQLITE_OK on no error
694//
695- (int)reset;
696
697//  Check if the SQLite parser recognizes the receiver as one or more valid
698//  SQLite statements.
699//
700//  Returns:
701//    YES if the string is a complete and valid SQLite statement
702//
703+ (BOOL)isCompleteStatement:(NSString *)string;
704
705//  Quote and escape the receiver for SQL.
706//  Example: "This is wild! It's fun!"
707//  Becomes: "'This is wild! It''s fun!'"
708//
709//  Returns:
710//    Autoreleased NSString
711+ (NSString *)quoteAndEscapeString:(NSString *)string;
712
713@end