Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Made it possible to have read-only databases which contain reference …

…tables.
  • Loading branch information...
commit 47a11e15dd2995efc193ca194eb304aac34d927e 1 parent 2b5604b
@ziminji authored
View
3  README.md
@@ -34,6 +34,7 @@ The following is a short-list of some of the features:
* [Automatic reference counting](http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/);
* Cleanly wraps-up the sqlite3 C based functions.
* Automatically places the SQLite database in the "Document" directory.
+* Allows for read-only databases.
* Provides multi-threading support for asynchronous SQLite database calls;
* Utilizes a PLIST file for setting up connection configurations;
* Allows database privileges to be restricted.
@@ -152,7 +153,7 @@ Help expand this list with your feedback.
## License (Apache v2.0)
-Copyright 2011 Ziminji
+Copyright 2011-2012 Ziminji
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the
License. You may obtain a copy of the License at:
View
4 cfg/db.plist
@@ -13,6 +13,8 @@
<string>UPDATE</string>
<string>DELETE</string>
</array>
+ <key>readonly</key>
+ <false/>
<key>type</key>
<string>SQLite</string>
</dict>
@@ -20,6 +22,8 @@
<dict>
<key>database</key>
<string>testdb.sqlite</string>
+ <key>readonly</key>
+ <false/>
<key>type</key>
<string>SQLite</string>
</dict>
View
12 gen/ZIMGenModels.sh
@@ -354,11 +354,9 @@ if [ $ARGCT -ge 1 -a -e $1 ]; then
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 1> $PLIST
echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" 1>> $PLIST
echo "<plist version=\"1.0\">" 1>> $PLIST
- echo -e "<dict>" 1>> $PLIST
- echo -e "\t<key>$DATA_SOURCE</key>" 1>> $PLIST
+ echo -e "<dict>" 1>> $PLIST
+ echo -e "\t<key>$DATA_SOURCE</key>" 1>> $PLIST
echo -e "\t<dict>" 1>> $PLIST
- echo -e "\t\t<key>type</key>" 1>> $PLIST
- echo -e "\t\t<string>SQLite</string>" 1>> $PLIST
echo -e "\t\t<key>database</key>" 1>> $PLIST
echo -e "\t\t<string>$database</string>" 1>> $PLIST
echo -e "\t\t<key>privileges</key>" 1>> $PLIST
@@ -368,9 +366,13 @@ if [ $ARGCT -ge 1 -a -e $1 ]; then
echo -e "\t\t\t<string>UPDATE</string>" 1>> $PLIST
echo -e "\t\t\t<string>DELETE</string>" 1>> $PLIST
echo -e "\t\t</array>" 1>> $PLIST
+ echo -e "\t\t<key>readonly</key>" 1>> $PLIST
+ echo -e "\t\t<false/>" 1>> $PLIST
+ echo -e "\t\t<key>type</key>" 1>> $PLIST
+ echo -e "\t\t<string>SQLite</string>" 1>> $PLIST
echo -e "\t</dict>" 1>> $PLIST
echo -e "</dict>" 1>> $PLIST
- echo "</plist>" 1>> $PLIST
+ echo "</plist>" 1>> $PLIST
##
# Indicates that the BASH script is done.
View
7 src/db/ZIMDbConnection.h
@@ -20,12 +20,13 @@
/*!
@class ZIMDbConnection
@discussion This class represents an SQLite database connection.
- @updated 2011-07-16
+ @updated 2012-03-23
*/
@interface ZIMDbConnection : NSObject {
@protected
NSString *_dataSource;
+ BOOL _readonly;
NSMutableSet *_privileges;
NSLock *_mutex;
sqlite3 *_database;
@@ -42,7 +43,7 @@
@param dataSource The file name of the database's PLIST to be used.
@param multithreading This determines whether locks should be used.
@return An instance of this class.
- @updated 2012-03-20
+ @updated 2012-03-23
*/
- (id) initWithDataSource: (NSString *)dataSource withMultithreadingSupport: (BOOL)multithreading;
/*!
@@ -77,7 +78,7 @@
possible to execute multiple SQL statements via this method.)
@param sql The SQL statement to be used.
@return Either the last insert row id or TRUE.
- @updated 2011-08-11
+ @updated 2012-03-23
@see http://www.sqlite.org/c3ref/last_insert_rowid.html
@see http://code.google.com/p/sqlite-manager/issues/detail?id=34
*/
View
43 src/db/ZIMDbConnection.m
@@ -76,18 +76,30 @@ - (id) initWithDataSource: (NSString *)dataSource withMultithreadingSupport: (BO
if ((type == nil) || ![[type lowercaseString] isEqualToString: @"sqlite"] || (database == nil)) {
@throw [NSException exceptionWithName: @"ZIMDbException" reason: @"Failed to load data source." userInfo: nil];
}
- NSFileManager *fileManager = [[NSFileManager alloc] init];
- NSString *workingPath = [NSString pathWithComponents: [NSArray arrayWithObjects: [(NSArray *)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0], database, nil]];
- if (![fileManager fileExistsAtPath: workingPath]) {
+ NSFileManager *fileManager = [[NSFileManager alloc] init];
+ NSString *readonly = [config objectForKey: @"readonly"];
+ if ((readonly != nil) && [readonly boolValue]) {
NSString *resourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: database];
- if ([fileManager fileExistsAtPath: resourcePath]) {
- NSError *error = nil;
- if (![fileManager copyItemAtPath: resourcePath toPath: workingPath error: &error]) {
- @throw [NSException exceptionWithName: @"ZIMDbException" reason: [NSString stringWithFormat: @"Failed to copy data source in resource directory to working directory. '%@'", [error localizedDescription]] userInfo: nil];
- }
+ if (![fileManager fileExistsAtPath: resourcePath]) {
+ @throw [NSException exceptionWithName: @"ZIMDbException" reason: @"Failed to find data source in resource directory." userInfo: nil];
}
- }
- _dataSource = [workingPath copy];
+ _dataSource = [resourcePath copy];
+ _readonly = YES;
+ }
+ else {
+ NSString *workingPath = [NSString pathWithComponents: [NSArray arrayWithObjects: [(NSArray *)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0], database, nil]];
+ if (![fileManager fileExistsAtPath: workingPath]) {
+ NSString *resourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: database];
+ if ([fileManager fileExistsAtPath: resourcePath]) {
+ NSError *error = nil;
+ if (![fileManager copyItemAtPath: resourcePath toPath: workingPath error: &error]) {
+ @throw [NSException exceptionWithName: @"ZIMDbException" reason: [NSString stringWithFormat: @"Failed to copy data source in resource directory to working directory. '%@'", [error localizedDescription]] userInfo: nil];
+ }
+ }
+ }
+ _dataSource = [workingPath copy];
+ _readonly = NO;
+ }
NSArray *privileges = [config objectForKey: @"privileges"];
if (privileges != nil) {
_privileges = [[NSMutableSet alloc] init];
@@ -133,7 +145,7 @@ - (NSNumber *) execute: (NSString *)sql {
NSString *command = [[NSString firstTokenInString: sql scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString: @" ;\"'`[]\n\r\t"]] uppercaseString];
- if ((_privileges != nil) && ![_privileges containsObject: command]) {
+ if (((_privileges != nil) && ![_privileges containsObject: command]) || _readonly) {
if (_mutex != nil) {
[_mutex unlock];
}
@@ -154,8 +166,13 @@ - (NSNumber *) execute: (NSString *)sql {
NSNumber *result = nil;
if ([command isEqualToString: @"INSERT"]) {
- // Known limitations: http://www.sqlite.org/c3ref/last_insert_rowid.html
- result = [NSNumber numberWithInt: sqlite3_last_insert_rowid(_database)];
+ @try {
+ // Known limitations: http://www.sqlite.org/c3ref/last_insert_rowid.html
+ result = [NSNumber numberWithInt: sqlite3_last_insert_rowid(_database)];
+ }
+ @catch (NSException *exception) {
+ result = [NSNumber numberWithInt: 0];
+ }
}
else {
result = [NSNumber numberWithBool: YES];
Please sign in to comment.
Something went wrong with that request. Please try again.