-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NULL Values not saved or returned properly #15
Comments
This is the function,
|
case SQLITE_BLOB:
|
yip, missing something to do for null and blob
ns-1m comments might work ... |
The problem is also when entering data it will not enter as null. Was able add the option for case SQLITE_NULL and SQLITE_BLOB as per my code above, however that's only part of the problem since data is not saved as null. |
This is a fix I came up with: https://github.com/marcucio/Phonegap-SQLitePlugin/commit/8660ba16fd796ad764e0c8a1eda906c47dbf8b57 maybe it fixes your issue |
Looks like will work.. will give it a go. Can you also update the project and add the corresponding code for the case SQLITE_BLOB and SQLITE_NULL.. I updated my version with the following.. case SQLITE_ROW:
|
@ecanas your code seems not to work for me, please post a diff or the entire file, maybe i missed something |
Here is the complete code, with the latest change you made. Will see if tomorrow I can post just the difference.. but the only changes are on the line "NSMutableArray *row = [[NSMutableArray alloc] initWithCapacity:count];" /*
#import "PGSQLitePlugin.h" @implementation PGSQLitePlugin @synthesize openDBs; -(PGPlugin_) initWithWebView:(UIWebView_)theWebView
} -(void) respond: (id)cb withString:(NSString )str withType:(NSString *)type { -(id) getDBPath:(id)dbFile { -(void) open: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options
} -(void) backgroundExecuteSqlBatch: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options -(void) backgroundExecuteSql: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options -(void) _executeSqlBatch:(NSMutableDictionary*)options -(void) _executeSql:(NSMutableDictionary*)options -(void) executeSqlBatch: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options -(void) executeSql: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options
} -(void) close: (NSMutableArray_)arguments withDict:(NSMutableDictionary_)options
} -(void)dealloc
} |
I try to use this patch above Cordova 1.5, app is crashing. |
marcucio, I made a few other changes now it's 100% working with nulls. Where can I post the 2 updated files. |
If you are set up for github you can add it to your account if not you can use gist: |
Ok..used gist.. here is the link |
It seems that null values are either not being saved or returned properly. Instead of saving a null value in a field I get 0 or '' depending on the datatype.
Below is code from QuickConnect which has a native client, maybe you can use some of the code, I noticed they have a blob section which you can use on your code and they have a function called "sqlite3_bind_null" not sure what it's doing exactly but could fix the null value problem.
/*
Copyright (c) 2008, 2009 Lee Barney
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
The end-user documentation included with the redistribution, if any, must
include the following acknowledgment:
"This product was created using the QuickConnect framework. http://www.quickconnectfamily.org",
in the same place and form as other third-party acknowledgments. Alternately, this acknowledgment
may appear in the software itself, in the same form and location as other
such third-party acknowledgments.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import "SQLiteDataAccess.h"
import "QCParameter.h"
import <unistd.h>
static NSString *dbSemaphore = @"dblock";
// Private interface for AppDelegate - internal only methods.
@interface SQLiteDataAccess (Private)
//internal bind methods
@EnD
@implementation SQLiteDataAccess
(SQLiteDataAccess_)initWithDatabase: (NSString_) dbName isWriteable: (BOOL) isWriteable{
//if (self = [super init]) {
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];
if(isWriteable){
}
sqlite3 *aDatabase;
//NSLog(@"path: %@",path);
if (sqlite3_open([path UTF8String], &aDatabase) == SQLITE_OK) {
//NSLog(@"database opened");
self->database = aDatabase;
}
else{
//since we failed to open the database completely close it down to make sure that everyting is cleaned up
sqlite3_close(aDatabase);
NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(aDatabase));
}
//}
return nil;
}
(DataAccessResult_)getData:(NSString_)SQL withParameters:(NSArray*)parameters{
//NSLog(@"getting data");
return [self dbAccess:SQL withParameters:parameters treatAsChangeData:FALSE];
}
(DataAccessResult_)setData:(NSString_)SQL withParameters:(NSArray*)parameters{
DataAccessResult *retVal;
@synchronized(dbSemaphore) {
retVal = [self dbAccess:SQL withParameters:parameters treatAsChangeData:TRUE];
}
return retVal;
}
(DataAccessResult_)dbAccess:(NSString_)SQL withParameters:(NSArray_)parameters treatAsChangeData:(BOOL)treatAsChangeData{
SQL = [SQL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//NSLog(@"paramArrayString after 1: %@\n\n\n",SQL);
//NSLog(@"in dbAccess");
DataAccessResult *theResult; //what is being returned
theResult = [DataAccessResult alloc];
if(parameters != nil && [parameters count] > 0){
//make sure the the number of parameters is equal to the number of qestion marks in the SQL string
}
int numResultColumns = 0;
sqlite3_stmt *statement = nil; // Preparing a statement compiles the SQL query into a byte-code program in the SQLite library.
// The third parameter is either the length of the SQL string or -1 to read up to the first null terminator.
const char_ SQLChar = [SQL UTF8String];//this needs to be deallocated after we don't need it any more.
//NSLog(@"about to prepare %@",SQL);
if (sqlite3_prepare_v2(database, SQLChar, -1, &statement, NULL) == SQLITE_OK) {
if(!treatAsChangeData){
//NSLog(@"columns not changing");
//retrieve the number of columns in the result of the execution of the select statement
numResultColumns = sqlite3_column_count(statement);
//NSLog(@"numRecentColumns: %i",numResultColumns);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *fieldNames = [[NSMutableArray alloc] initWithCapacity:0];
for(int i = 0; i < numResultColumns; i++){
const char *name = sqlite3_column_name(statement, i);
NSString * columnName = [[NSString alloc]initWithCString:name encoding:NSUTF8StringEncoding];
[fieldNames addObject:columnName];
[columnName autorelease];
}
[theResult setFieldNames:fieldNames];
[fieldNames autorelease];
}
else{
/*NSString *error;
error = [[NSString alloc]initWithCString:sqlite3_errmsg(database) encoding:NSASCIIStringEncoding];
[theResult setErrorDescription:error];
[error release];
*/
[theResult setErrorDescription:[NSString stringWithUTF8String:sqlite3_errmsg(database)]];
}
// "Finalize" the statement - releases the resources associated with the statement.
sqlite3_finalize(statement);
//[pool drain];
//NSLog(@"returning: %@",theResult);
return theResult;
}
(DataAccessResult_)startTransaction{
NSString_ sql = @"BEGIN EXCLUSIVE TRANSACTION";
return [self setData:sql withParameters:nil];
}
(DataAccessResult_)endTransaction{
NSString_ sql = @"COMMIT";
return [self setData:sql withParameters:nil];
}
NSString_ sql = @"ROLLBACK";
return [self setData:sql withParameters:nil];
}
if (sqlite3_close(database) != SQLITE_OK) {
NSAssert1(0, @"Error: failed to close database with message '%s'.", sqlite3_errmsg(database));
}
}
// internal bind methods
(int) bind_blob:(sqlite3_stmt_)statement withIndex:(int)parameterIndex andBindVariable:(NSData_)aVariable{
if (![aVariable respondsToSelector:@selector(lengthOfBytes:)]) {
return -1;
}
//by default have the library make a copy, SQLITE_TRANSIENT, since we don't know if the variable may be changed
//by something else in the application.
return sqlite3_bind_blob(statement, parameterIndex, aVariable, [aVariable length], SQLITE_TRANSIENT);
}
(int) bind_double:(sqlite3_stmt*)statement withIndex:(int)parameterIndex andBindVariable:(id)aVariable{
//NSLog(@"binding parameter %i", parameterIndex);
return sqlite3_bind_double(statement, parameterIndex, [aVariable doubleValue]);
}
(int) bind_int:(sqlite3_stmt*)statement withIndex:(int)parameterIndex andBindVariable:(id)aVariable{
return sqlite3_bind_int(statement, parameterIndex, [aVariable integerValue]);
}
(int) bind_text:(sqlite3_stmt_)statement withIndex:(int)parameterIndex andBindVariable:(id)aVariable{
//NSLog(@"binding parameter %i", parameterIndex);
//assume an ASCII string
const char_ valueChars = [aVariable cStringUsingEncoding:NSUTF8StringEncoding];
return sqlite3_bind_text(statement, parameterIndex, valueChars, [aVariable lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_TRANSIENT);
}
(int) bind_zeroblob:(sqlite3_stmt*)statement withIndex:(int)parameterIndex andBindVariable:(int)aVariable{
return sqlite3_bind_zeroblob(statement, parameterIndex, aVariable);
}
(int) bind_null:(sqlite3_stmt*)statement withIndex:(int)parameterIndex andBindVariable:(id)aVariable{
return sqlite3_bind_null(statement, parameterIndex);
}
(void)dealloc {
[bindTypeDictionary release];
[super dealloc];
}
@EnD
The text was updated successfully, but these errors were encountered: