Assertion failure in sqlite3 using XCode, binding problem? - xcode

-(void)updatepw{
databaseName=#"bestfb.sqlite";
NSArray *documnetPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documnetDir =[documnetPath objectAtIndex:0];
databasePath=[documnetDir stringByAppendingPathComponent:databaseName];
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSString *update = [[NSString alloc] initWithFormat:#"update staff set pword = %# where staffID=1;", todb];
sqlite3_stmt *selectstmt;
const char *sql= (char *) update;
NSLog(#"new sql :%#", sql);
NSLog(#"values: %#", newpw.text);
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) ==SQLITE_OK){
NSLog(#"prepare failed");
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
else {
sqlite3_bind_text(selectstmt, 1, [todb UTF8String], -1, SQLITE_TRANSIENT);
NSLog(#"binding done");
}
int success1 = sqlite3_step(selectstmt);
if (success1 != SQLITE_DONE) {
NSAssert1(0, #"Error: failed to save priority with message '%s'.", sqlite3_errmsg(database));
}
sqlite3_finalize(selectstmt);
}
sqlite3_close(database);
}
Hi all, I've been working on solving the error for hours.
I could not get the database to update, it would just crash whenever I tries to update.
Anyone who can help is the most welcome!
Please be gentle, as I am only a newbie to XCode.

I think you have missed the single quotes in the below sentence before and after %#
replace with this.
NSString *update = [[NSString alloc] initWithFormat:#"update staff set pword = '%#' where staffID=1;", todb];

Related

Error with Firebase/Messaging in iOS when create table

I have a error in iOS with xcode 12.5.1.
When I open the app it crashed.
This happens when execute line FirebaseApp.configure() in AppDelegate.swift class
pod 'Firebase/Messaging' - FirebaseMessaging (7.11.0)
Error: 2021-08-16 01:13:02.476120-0500 bm[7585:1201692] [logging] file
is not a database in "create TABLE IF NOT EXISTS incomingSyncMessages
(_id INTEGER PRIMARY KEY, rmq_id TEXT, expiration_ts INTEGER,
apns_recv INTEGER, mcs_recv INTEGER)"
2021-08-16 01:13:11.138855-0500 bm[7585:1201692] *** Assertion failure
in -[FIRMessagingRmqManager createTableWithName:command:],
FIRMessagingRmqManager.m:456
2021-08-16 01:13:11.140170-0500 bm[7585:1201692] *** Terminating app
due to uncaught exception 'NSInternalInconsistencyException', reason:
'Couldn't create table: create TABLE IF NOT EXISTS Couldn't create
table: create TABLE IF NOT EXISTS %#%# (_id INTEGER PRIMARY KEY,
rmq_id INTEGER, type INTEGER, ts INTEGER, data BLOB) file is not a
database34-62-25736 (_id INTEGER PRIMARY KEY, rmq_id INTEGER, type
INTEGER, ts INTEGER, data BLOB) file is not a database'
*** First throw call stack: (0x1a82b725c 0x1bc04c480 0x1a81c4c98 0x1a94fcef8 0x10510283c 0x1051030b0 0x108063ae8 0x10806532c
0x10806c38c 0x10806d010 0x108078820 0x1f07e95bc 0x1f07ec86c)
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't create table:
create TABLE IF NOT EXISTS Couldn't create table: create TABLE IF NOT
EXISTS %#%# (_id INTEGER PRIMARY KEY, rmq_id INTEGER, type INTEGER, ts
INTEGER, data BLOB) file is not a database34-62-25736 (_id INTEGER
PRIMARY KEY, rmq_id INTEGER, type INTEGER, ts INTEGER, data BLOB) file
is not a database' terminating with uncaught exception of type
NSException
FIRMessagingRmqManager.m:
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h"
#import <sqlite3.h>
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
#import "FirebaseMessaging/Sources/FIRMessagingDefines.h"
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
#import "FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h"
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h"
#ifndef _FIRMessagingRmqLogAndExit
#define _FIRMessagingRmqLogAndExit(stmt, return_value) \
do { \
[self logErrorAndFinalizeStatement:stmt]; \
return return_value; \
} while (0)
#endif
#ifndef FIRMessagingRmqLogAndReturn
#define FIRMessagingRmqLogAndReturn(stmt) \
do { \
[self logErrorAndFinalizeStatement:stmt]; \
return; \
} while (0)
#endif
#ifndef FIRMessaging_MUST_NOT_BE_MAIN_THREAD
#define FIRMessaging_MUST_NOT_BE_MAIN_THREAD() \
do { \
NSAssert(![NSThread isMainThread], #"Must not be executing on the main thread."); \
} while (0);
#endif
// table names
NSString *const kTableOutgoingRmqMessages = #"outgoingRmqMessages";
NSString *const kTableLastRmqId = #"lastrmqid";
NSString *const kOldTableS2DRmqIds = #"s2dRmqIds";
NSString *const kTableS2DRmqIds = #"s2dRmqIds_1";
// Used to prevent de-duping of sync messages received both via APNS and MCS.
NSString *const kTableSyncMessages = #"incomingSyncMessages";
static NSString *const kTablePrefix = #"";
// create tables
static NSString *const kCreateTableOutgoingRmqMessages = #"create TABLE IF NOT EXISTS %#%# "
#"(_id INTEGER PRIMARY KEY, "
#"rmq_id INTEGER, "
#"type INTEGER, "
#"ts INTEGER, "
#"data BLOB)";
static NSString *const kCreateTableLastRmqId = #"create TABLE IF NOT EXISTS %#%# "
#"(_id INTEGER PRIMARY KEY, "
#"rmq_id INTEGER)";
static NSString *const kCreateTableS2DRmqIds = #"create TABLE IF NOT EXISTS %#%# "
#"(_id INTEGER PRIMARY KEY, "
#"rmq_id TEXT)";
static NSString *const kCreateTableSyncMessages = #"create TABLE IF NOT EXISTS %#%# "
#"(_id INTEGER PRIMARY KEY, "
#"rmq_id TEXT, "
#"expiration_ts INTEGER, "
#"apns_recv INTEGER, "
#"mcs_recv INTEGER)";
static NSString *const kDropTableCommand = #"drop TABLE if exists %#%#";
// table infos
static NSString *const kRmqIdColumn = #"rmq_id";
static NSString *const kDataColumn = #"data";
static NSString *const kProtobufTagColumn = #"type";
static NSString *const kIdColumn = #"_id";
static NSString *const kOutgoingRmqMessagesColumns = #"rmq_id, type, data";
// Sync message columns
static NSString *const kSyncMessagesColumns = #"rmq_id, expiration_ts, apns_recv, mcs_recv";
// Message time expiration in seconds since 1970
static NSString *const kSyncMessageExpirationTimestampColumn = #"expiration_ts";
static NSString *const kSyncMessageAPNSReceivedColumn = #"apns_recv";
static NSString *const kSyncMessageMCSReceivedColumn = #"mcs_recv";
// Utility to create an NSString from a sqlite3 result code
NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
const char *errorStr = sqlite3_errstr(result);
#pragma clang diagnostic pop
NSString *errorString = [NSString stringWithFormat:#"%d - %s", result, errorStr];
return errorString;
}
#interface FIRMessagingRmqManager () {
sqlite3 *_database;
/// Serial queue for database read/write operations.
dispatch_queue_t _databaseOperationQueue;
}
#property(nonatomic, readwrite, strong) NSString *databaseName;
// map the category of an outgoing message with the number of messages for that category
// should always have two keys -- the app, gcm
#property(nonatomic, readwrite, strong) NSMutableDictionary *outstandingMessages;
// Outgoing RMQ persistent id
#property(nonatomic, readwrite, assign) int64_t rmqId;
#end
#implementation FIRMessagingRmqManager
- (instancetype)initWithDatabaseName:(NSString *)databaseName {
self = [super init];
if (self) {
_databaseOperationQueue =
dispatch_queue_create("com.google.firebase.messaging.database.rmq", DISPATCH_QUEUE_SERIAL);
_databaseName = [databaseName copy];
[self openDatabase];
_outstandingMessages = [NSMutableDictionary dictionaryWithCapacity:2];
_rmqId = -1;
}
return self;
}
- (void)dealloc {
sqlite3_close(_database);
}
#pragma mark - RMQ ID
- (void)loadRmqId {
if (self.rmqId >= 0) {
return; // already done
}
[self loadInitialOutgoingPersistentId];
if (self.outstandingMessages.count) {
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmqManager000, #"Outstanding categories %ld",
_FIRMessaging_UL(self.outstandingMessages.count));
}
}
/**
* Initialize the 'initial RMQ':
* - max ID of any message in the queue
* - if the queue is empty, stored value in separate DB.
*
* Stream acks will remove from RMQ, when we remove the highest message we keep track
* of its ID.
*/
- (void)loadInitialOutgoingPersistentId {
// we shouldn't always trust the lastRmqId stored in the LastRmqId table, because
// we only save to the LastRmqId table once in a while (after getting the lastRmqId sent
// by the server after reconnect, and after getting a rmq ack from the server). The
// rmq message with the highest rmq id tells the real story, so check against that first.
__block int64_t rmqId;
dispatch_sync(_databaseOperationQueue, ^{
rmqId = [self queryHighestRmqId];
});
if (rmqId == 0) {
dispatch_sync(_databaseOperationQueue, ^{
rmqId = [self queryLastRmqId];
});
}
self.rmqId = rmqId + 1;
}
/**
* This is called when we delete the largest outgoing message from queue.
*/
- (void)saveLastOutgoingRmqId:(int64_t)rmqID {
dispatch_async(_databaseOperationQueue, ^{
NSString *queryFormat = #"INSERT OR REPLACE INTO %# (%#, %#) VALUES (?, ?)";
NSString *query = [NSString stringWithFormat:queryFormat,
kTableLastRmqId, // table
kIdColumn, kRmqIdColumn]; // columns
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &statement, NULL) !=
SQLITE_OK) {
FIRMessagingRmqLogAndReturn(statement);
}
if (sqlite3_bind_int(statement, 1, 1) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(statement);
}
if (sqlite3_bind_int64(statement, 2, rmqID) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(statement);
}
if (sqlite3_step(statement) != SQLITE_DONE) {
FIRMessagingRmqLogAndReturn(statement);
}
sqlite3_finalize(statement);
});
}
- (void)saveS2dMessageWithRmqId:(NSString *)rmqId {
dispatch_async(_databaseOperationQueue, ^{
NSString *insertFormat = #"INSERT INTO %# (%#) VALUES (?)";
NSString *insertSQL = [NSString stringWithFormat:insertFormat, kTableS2DRmqIds, kRmqIdColumn];
sqlite3_stmt *insert_statement;
if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &insert_statement, NULL) !=
SQLITE_OK) {
FIRMessagingRmqLogAndReturn(insert_statement);
}
if (sqlite3_bind_text(insert_statement, 1, [rmqId UTF8String], (int)[rmqId length],
SQLITE_STATIC) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(insert_statement);
}
if (sqlite3_step(insert_statement) != SQLITE_DONE) {
FIRMessagingRmqLogAndReturn(insert_statement);
}
sqlite3_finalize(insert_statement);
});
}
#pragma mark - Query
- (int64_t)queryHighestRmqId {
NSString *queryFormat = #"SELECT %# FROM %# ORDER BY %# DESC LIMIT %d";
NSString *query = [NSString stringWithFormat:queryFormat,
kRmqIdColumn, // column
kTableOutgoingRmqMessages, // table
kRmqIdColumn, // order by column
1]; // limit
sqlite3_stmt *statement;
int64_t highestRmqId = 0;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(statement, highestRmqId);
}
if (sqlite3_step(statement) == SQLITE_ROW) {
highestRmqId = sqlite3_column_int64(statement, 0);
}
sqlite3_finalize(statement);
return highestRmqId;
}
- (int64_t)queryLastRmqId {
NSString *queryFormat = #"SELECT %# FROM %# ORDER BY %# DESC LIMIT %d";
NSString *query = [NSString stringWithFormat:queryFormat,
kRmqIdColumn, // column
kTableLastRmqId, // table
kRmqIdColumn, // order by column
1]; // limit
sqlite3_stmt *statement;
int64_t lastRmqId = 0;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(statement, lastRmqId);
}
if (sqlite3_step(statement) == SQLITE_ROW) {
lastRmqId = sqlite3_column_int64(statement, 0);
}
sqlite3_finalize(statement);
return lastRmqId;
}
#pragma mark - Sync Messages
- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID {
__block FIRMessagingPersistentSyncMessage *persistentMessage;
dispatch_sync(_databaseOperationQueue, ^{
NSString *queryFormat = #"SELECT %# FROM %# WHERE %# = '%#'";
NSString *query =
[NSString stringWithFormat:queryFormat,
kSyncMessagesColumns, // SELECT (rmq_id, expiration_ts,
// apns_recv, mcs_recv)
kTableSyncMessages, // FROM sync_rmq
kRmqIdColumn, // WHERE rmq_id
rmqID];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
[self logError];
sqlite3_finalize(stmt);
return;
}
const int rmqIDColumn = 0;
const int expirationTimestampColumn = 1;
const int apnsReceivedColumn = 2;
const int mcsReceivedColumn = 3;
int count = 0;
while (sqlite3_step(stmt) == SQLITE_ROW) {
NSString *rmqID =
[NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, rmqIDColumn)];
int64_t expirationTimestamp = sqlite3_column_int64(stmt, expirationTimestampColumn);
BOOL apnsReceived = sqlite3_column_int(stmt, apnsReceivedColumn);
BOOL mcsReceived = sqlite3_column_int(stmt, mcsReceivedColumn);
// create a new persistent message
persistentMessage =
[[FIRMessagingPersistentSyncMessage alloc] initWithRMQID:rmqID
expirationTime:expirationTimestamp];
persistentMessage.apnsReceived = apnsReceived;
persistentMessage.mcsReceived = mcsReceived;
count++;
}
sqlite3_finalize(stmt);
});
return persistentMessage;
}
- (void)deleteExpiredOrFinishedSyncMessages {
dispatch_async(_databaseOperationQueue, ^{
int64_t now = FIRMessagingCurrentTimestampInSeconds();
NSString *deleteSQL = #"DELETE FROM %# "
#"WHERE %# < %lld OR " // expirationTime < now
#"(%# = 1 AND %# = 1)"; // apns_received = 1 AND mcs_received = 1
NSString *query = [NSString
stringWithFormat:deleteSQL, kTableSyncMessages, kSyncMessageExpirationTimestampColumn, now,
kSyncMessageAPNSReceivedColumn, kSyncMessageMCSReceivedColumn];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
FIRMessagingRmqLogAndReturn(stmt);
}
sqlite3_finalize(stmt);
int deleteCount = sqlite3_changes(self->_database);
if (deleteCount > 0) {
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSyncMessageManager001,
#"Successfully deleted %d sync messages from store", deleteCount);
}
});
}
- (void)saveSyncMessageWithRmqID:(NSString *)rmqID expirationTime:(int64_t)expirationTime {
BOOL apnsReceived = YES;
BOOL mcsReceived = NO;
dispatch_async(_databaseOperationQueue, ^{
NSString *insertFormat = #"INSERT INTO %# (%#, %#, %#, %#) VALUES (?, ?, ?, ?)";
NSString *insertSQL =
[NSString stringWithFormat:insertFormat,
kTableSyncMessages, // Table name
kRmqIdColumn, // rmq_id
kSyncMessageExpirationTimestampColumn, // expiration_ts
kSyncMessageAPNSReceivedColumn, // apns_recv
kSyncMessageMCSReceivedColumn /* mcs_recv */];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_bind_int64(stmt, 2, expirationTime) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_bind_int(stmt, 3, apnsReceived ? 1 : 0) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_bind_int(stmt, 4, mcsReceived ? 1 : 0) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(stmt);
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
FIRMessagingRmqLogAndReturn(stmt);
}
sqlite3_finalize(stmt);
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager004,
#"Added sync message to cache: %#", rmqID);
});
}
- (void)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID {
dispatch_async(_databaseOperationQueue, ^{
if (![self updateSyncMessageWithRmqID:rmqID column:kSyncMessageAPNSReceivedColumn value:YES]) {
FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager005,
#"Failed to update APNS state for sync message %#", rmqID);
}
});
}
- (BOOL)updateSyncMessageWithRmqID:(NSString *)rmqID column:(NSString *)column value:(BOOL)value {
FIRMessaging_MUST_NOT_BE_MAIN_THREAD();
NSString *queryFormat = #"UPDATE %# " // Table name
#"SET %# = %d " // column=value
#"WHERE %# = ?"; // condition
NSString *query = [NSString
stringWithFormat:queryFormat, kTableSyncMessages, column, value ? 1 : 0, kRmqIdColumn];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(stmt, NO);
}
if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(stmt, NO);
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
_FIRMessagingRmqLogAndExit(stmt, NO);
}
sqlite3_finalize(stmt);
return YES;
}
#pragma mark - Database
- (NSString *)pathForDatabase {
return [[self class] pathForDatabaseWithName:_databaseName];
}
+ (NSString *)pathForDatabaseWithName:(NSString *)databaseName {
NSString *dbNameWithExtension = [NSString stringWithFormat:#"%#.sqlite", databaseName];
NSArray *paths =
NSSearchPathForDirectoriesInDomains(FIRMessagingSupportedDirectory(), NSUserDomainMask, YES);
NSArray *components = #[ paths.lastObject, kFIRMessagingSubDirectoryName, dbNameWithExtension ];
return [NSString pathWithComponents:components];
}
- (void)createTableWithName:(NSString *)tableName command:(NSString *)command {
FIRMessaging_MUST_NOT_BE_MAIN_THREAD();
char *error;
NSString *createDatabase = [NSString stringWithFormat:command, kTablePrefix, tableName];
if (sqlite3_exec(self->_database, [createDatabase UTF8String], NULL, NULL, &error) != SQLITE_OK) {
// remove db before failing
[self removeDatabase];
NSString *errorMessage = [NSString
stringWithFormat:#"Couldn't create table: %# %#", kCreateTableOutgoingRmqMessages,
[NSString stringWithCString:error encoding:NSUTF8StringEncoding]];
FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingTable, #"%#",
errorMessage);
NSAssert(NO, errorMessage);
}
}
- (void)dropTableWithName:(NSString *)tableName {
FIRMessaging_MUST_NOT_BE_MAIN_THREAD();
char *error;
NSString *dropTableSQL = [NSString stringWithFormat:kDropTableCommand, kTablePrefix, tableName];
if (sqlite3_exec(self->_database, [dropTableSQL UTF8String], NULL, NULL, &error) != SQLITE_OK) {
FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore002,
#"Failed to remove table %#", tableName);
}
}
- (void)removeDatabase {
// Ensure database is removed in a sync queue as this sometimes makes test have race conditions.
dispatch_async(_databaseOperationQueue, ^{
NSString *path = [self pathForDatabase];
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
});
}
- (void)openDatabase {
dispatch_async(_databaseOperationQueue, ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self pathForDatabase];
BOOL didOpenDatabase = YES;
if (![fileManager fileExistsAtPath:path]) {
// We've to separate between different versions here because of backwards compatbility issues.
int result = sqlite3_open_v2(
[path UTF8String], &self -> _database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL);
if (result != SQLITE_OK) {
NSString *errorString = FIRMessagingStringFromSQLiteResult(result);
NSString *errorMessage = [NSString
stringWithFormat:#"Could not open existing RMQ database at path %#, error: %#", path,
errorString];
FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase,
#"%#", errorMessage);
NSAssert(NO, errorMessage);
return;
}
[self createTableWithName:kTableOutgoingRmqMessages command:kCreateTableOutgoingRmqMessages];
[self createTableWithName:kTableLastRmqId command:kCreateTableLastRmqId];
[self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds];
} else {
// Calling sqlite3_open should create the database, since the file doesn't exist.
int result = sqlite3_open_v2(
[path UTF8String], &self -> _database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL);
if (result != SQLITE_OK) {
NSString *errorString = FIRMessagingStringFromSQLiteResult(result);
NSString *errorMessage =
[NSString stringWithFormat:#"Could not create RMQ database at path %#, error: %#", path,
errorString];
FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase,
#"%#", errorMessage);
NSAssert(NO, errorMessage);
didOpenDatabase = NO;
} else {
[self updateDBWithStringRmqID];
}
}
if (didOpenDatabase) {
[self createTableWithName:kTableSyncMessages command:kCreateTableSyncMessages];
}
});
}
- (void)updateDBWithStringRmqID {
dispatch_async(_databaseOperationQueue, ^{
[self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds];
[self dropTableWithName:kOldTableS2DRmqIds];
});
}
#pragma mark - Private
- (BOOL)saveMessageWithRmqId:(int64_t)rmqId tag:(int8_t)tag data:(NSData *)data {
FIRMessaging_MUST_NOT_BE_MAIN_THREAD();
NSString *insertFormat = #"INSERT INTO %# (%#, %#, %#) VALUES (?, ?, ?)";
NSString *insertSQL =
[NSString stringWithFormat:insertFormat,
kTableOutgoingRmqMessages, // table
kRmqIdColumn, kProtobufTagColumn, kDataColumn /* columns */];
sqlite3_stmt *insert_statement;
if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &insert_statement, NULL) !=
SQLITE_OK) {
_FIRMessagingRmqLogAndExit(insert_statement, NO);
}
if (sqlite3_bind_int64(insert_statement, 1, rmqId) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(insert_statement, NO);
}
if (sqlite3_bind_int(insert_statement, 2, tag) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(insert_statement, NO);
}
if (sqlite3_bind_blob(insert_statement, 3, [data bytes], (int)[data length], NULL) != SQLITE_OK) {
_FIRMessagingRmqLogAndExit(insert_statement, NO);
}
if (sqlite3_step(insert_statement) != SQLITE_DONE) {
_FIRMessagingRmqLogAndExit(insert_statement, NO);
}
sqlite3_finalize(insert_statement);
return YES;
}
- (void)deleteMessagesFromTable:(NSString *)tableName withRmqIds:(NSArray *)rmqIds {
dispatch_async(_databaseOperationQueue, ^{
BOOL isRmqIDString = NO;
// RmqID is a string only for outgoing messages
if ([tableName isEqualToString:kTableS2DRmqIds] ||
[tableName isEqualToString:kTableSyncMessages]) {
isRmqIDString = YES;
}
NSMutableString *delete =
[NSMutableString stringWithFormat:#"DELETE FROM %# WHERE ", tableName];
NSString *toDeleteArgument = [NSString stringWithFormat:#"%# = ? OR ", kRmqIdColumn];
int toDelete = (int)[rmqIds count];
if (toDelete == 0) {
return;
}
int maxBatchSize = 100;
int start = 0;
int deleteCount = 0;
while (start < toDelete) {
// construct the WHERE argument
int end = MIN(start + maxBatchSize, toDelete);
NSMutableString *whereArgument = [NSMutableString string];
for (int i = start; i < end; i++) {
[whereArgument appendString:toDeleteArgument];
}
// remove the last * OR * from argument
NSRange range = NSMakeRange([whereArgument length] - 4, 4);
[whereArgument deleteCharactersInRange:range];
NSString *deleteQuery = [NSString stringWithFormat:#"%# %#", delete, whereArgument];
// sqlite update
sqlite3_stmt *delete_statement;
if (sqlite3_prepare_v2(self->_database, [deleteQuery UTF8String], -1, &delete_statement,
NULL) != SQLITE_OK) {
FIRMessagingRmqLogAndReturn(delete_statement);
}
// bind values
int rmqIndex = 0;
int placeholderIndex = 1; // placeholders in sqlite3 start with 1
for (NSString *rmqId in rmqIds) { // objectAtIndex: is O(n) -- would make it slow
if (rmqIndex < start) {
rmqIndex++;
continue;
} else if (rmqIndex >= end) {
break;
} else {
if (isRmqIDString) {
if (sqlite3_bind_text(delete_statement, placeholderIndex, [rmqId UTF8String],
(int)[rmqId length], SQLITE_STATIC) != SQLITE_OK) {
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore003,
#"Failed to bind rmqID %#", rmqId);
FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager007,
#"Failed to delete sync message %#", rmqId);
continue;
}
} else {
int64_t rmqIdValue = [rmqId longLongValue];
sqlite3_bind_int64(delete_statement, placeholderIndex, rmqIdValue);
}
placeholderIndex++;
}
rmqIndex++;
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager008,
#"Successfully deleted sync message from cache %#", rmqId);
}
if (sqlite3_step(delete_statement) != SQLITE_DONE) {
FIRMessagingRmqLogAndReturn(delete_statement);
}
sqlite3_finalize(delete_statement);
deleteCount += sqlite3_changes(self->_database);
start = end;
}
// if we are here all of our sqlite queries should have succeeded
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore004,
#"Trying to delete %d s2D ID's, successfully deleted %d", toDelete,
deleteCount);
});
}
- (int64_t)nextRmqId {
return ++self.rmqId;
}
- (NSString *)lastErrorMessage {
return [NSString stringWithFormat:#"%s", sqlite3_errmsg(_database)];
}
- (int)lastErrorCode {
return sqlite3_errcode(_database);
}
- (void)logError {
FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore006,
#"Error: code (%d) message: %#", [self lastErrorCode],
[self lastErrorMessage]);
}
- (void)logErrorAndFinalizeStatement:(sqlite3_stmt *)stmt {
[self logError];
sqlite3_finalize(stmt);
}
- (dispatch_queue_t)databaseOperationQueue {
return _databaseOperationQueue;
}
#end
Thanks for your help.

Compare variable with SQLite values

I need to check if a variable has already been inserted on my SQLite db in order to change an image button, I tried to use this method but it's not working properly:
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &Preferiti) == SQLITE_OK)
{
NSString *checkSQL = [NSString stringWithFormat: #"SELECT * FROM ListaEventi WHERE idEvento=%#", [DettagliEvento objectAtIndex:7]];
const char *insert_stmt = [checkSQL UTF8String];
sqlite3_prepare_v2(Preferiti, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
[_preferito setImage:[UIImage imageNamed:#"staroff.png"] forState:UIControlStateNormal];
_preferito.tag=0;
} else {
[_preferito setImage:[UIImage imageNamed:#"staron.png"] forState:UIControlStateNormal];
_preferito.tag=1;
}
sqlite3_finalize(statement);
sqlite3_close(Preferiti);
}
Is there any other way to write the statement to compare a variable with values inside my SQLite table?

SecItemCopyMatching returns empty dictionary

For some reason I got an empty dictionary when calling SecItemCopyMatching on OSX 10.8.4. The corresponding item is in the keychain and contains username and password. SecItemCopyMatching founds it (errSecSuccess) but the result dictionary just contains 0 entries. I would expect it to have at least username and password data, so what's wrong with my request?
OSStatus status;
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[query setObject:(id)kSecReturnAttributes forKey:(id)kCFBooleanTrue];
[query setObject:#"MyService" forKey:(id)kSecAttrService];
CFDictionaryRef dictRef = NULL;
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dictRef);
if (status != errSecSuccess) {
CFStringRef errorRef = SecCopyErrorMessageString(status, NULL);
NSLog(#"%s: %#", __FUNCTION__, (__bridge NSString *)errorRef);
CFRelease(errorRef);
return nil;
}
// --> dictRef empty
if (dictRef != NULL) CFRelease(dictRef);
There is a mistake in the request. I've mixed up key and object.
[query setObject:(id)kSecReturnAttributes forKey:(id)kCFBooleanTrue];
must be
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
however as bdash pointed out, it will return only non-encrypted attributes like the username. To get the password there is another request necessary with passing
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
So here what I have now:
OSStatus status;
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
[query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[query setObject:#"MyService" forKey:(id)kSecAttrService];
// get username
CFDictionaryRef dictRef = NULL;
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dictRef);
if (status != errSecSuccess) {
CFStringRef errorRef = SecCopyErrorMessageString(status, NULL);
NSLog(#"%s: %#", __FUNCTION__, (__bridge NSString *)errorRef);
CFRelease(errorRef);
return nil;
}
NSString *username = (__bridge NSString *)CFDictionaryGetValue(dictRef, kSecAttrAccount);
CFRelease(dictRef);
// get password
[query removeObjectForKey:(id)kSecReturnAttributes];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
CFDataRef dataRef = NULL;
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&dataRef);
if (status != errSecSuccess) {
CFStringRef errorRef = SecCopyErrorMessageString(status, NULL);
NSLog(#"%s: %#", __FUNCTION__, (__bridge NSString *)errorRef);
CFRelease(errorRef);
return nil;
}
NSString *password = [[NSString alloc] initWithData:(__bridge NSData *)(dataRef) encoding:NSUTF8StringEncoding];
CFRelease(dataRef);

NSView Drag Operation Error

I'm coding in Cocoa, on OS X.
I'm trying to receive a file that is dragged and dropped onto my NSView subclass - which I can do; and get its contents and filename and display them - which I can do for any type of file first time, but on the second time, when I try and drag another file on, I can only set the title setTitle:, but not the main body text setText:
The errors I am getting are:
Canceling drag because exception 'NSInternalInconsistencyException' (reason 'Invalid parameter not satisfying: aString != nil') was raised during a dragging session
and
Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit-1187/AppKit.subproj/NSCell.m:1532
My code (sorry, it's quite long!):
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
NSPasteboard *pboard;
NSDragOperation sourceDragMask;
sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
NSURL *file = [NSURL URLFromPasteboard:pboard];
//NSData *data = [NSData dataWithContentsOfURL:file];
NSError *error;
NSStringEncoding encoding;
NSString *contentString = [[NSString alloc] initWithContentsOfURL:file usedEncoding:&encoding error:&error];
NSLog(#"Error: %#",error);
NSString *last = [[file path] lastPathComponent];
NSArray *parts = [last componentsSeparatedByString:#"."];
NSString *filename = [parts objectAtIndex:0];
NSString *fileType = [parts objectAtIndex:1];
NSLog(#"FILETYPE: %#", fileType);
if ([fileType isEqualToString:#"txt"] || [fileType isEqualToString:#"md"]) {
[self setTitle:filename];
if (self.textViewString == (id)[NSNull null] || self.textViewString.length == 0) {
[self setText:contentString];
} else {
BOOL whatToDo = (NSRunCriticalAlertPanel(#"What do you want to do?", nil, #"Append", #"Replace", nil) == NSAlertDefaultReturn);
if (whatToDo) {
//Append
[self setText:[NSString stringWithFormat:#"%#\n%#",self.textViewString,contentString]];
} else {
//Replace
[self setText:contentString];
}
}
return YES;
} else {
return NO;
}
} else if ([[pboard types] containsObject:NSPasteboardTypeString]) {
NSString *draggedString = [pboard stringForType:NSPasteboardTypeString];
if (self.textViewString == (id)[NSNull null] || self.textViewString.length == 0) {
[self setText:draggedString];
} else {
[self setText:[NSString stringWithFormat:#"%#\n%#",self.textViewString,draggedString]];
}
return YES;
}
else {
return NO;
}
}
Thanks in advance! :)
Sounds like Cocoa is canceling the drag when any exception is raised, and an exception is getting raised when something internally is expecting a string and is getting a nil value instead.
It's just a guess without having more information, but I would predict that stringWithFormat: is raising the exception, as it looks like the only really potentially fragile bit of what you have written.
You are doing a couple ill-advised things. First, you are assuming that -initWithContentsOfURL:usedEncoding:error: is succeeding. You should not do this. Instead, you need to pass an NSError ** that can be filled in on error, test whether contentString is nil, and, if so, check the error accordingly. I have a feeling that you will find you are getting nil, and the error will explain why.
Possibly unrelated, but your if (whatToDo) is not doing what you probably think it is. Since whatToDo is a pointer to an autoreleased NSNumber instance your conditional will always evaluate to true, since the pointer is non-zero. What you likely meant to do was something like the following:
BOOL whatToDo = (NSRunCriticalAlertPanel(#"What do you want to do?", nil, #"Append", #"Replace", nil) == NSAlertDefaultReturn);
if (whatToDo) {
//Append
[self setText:[NSString stringWithFormat:#"%#\n%#",self.textViewString,contentString]];
} else {
//Replace
[self setText:contentString];
}
Lots of thanks for the many tips and pieces of advice from this answer by Conrad Shultz! I've followed the advice and tips there.
However, my problem turned out to be very, very basic. It lied in the line BOOL whatToDo = (NSRunCriticalAlertPanel(#"What do you want to do?", nil, #"Append", #"Replace", nil) == NSAlertDefaultReturn);
It turns out a string must be passed to the second parameter, but I was passing nil. Fixed!

can't figure why insert sqlite sql statement is not being executed , Xcode

everything looks good for me, but the prepare_v2 doesn't get SQLITE_OK
the sql instruction is pretty basic, if I copy and paste it on the sqlite manager, it inserts fine
is there anything I am missing?
//from view controller
- (void)viewDidLoad
{
[super viewDidLoad];
DBConnection* dbCon = [DBConnection alloc];
[dbCon init];
[dbCon InsertDataRollNo:#"888"];
}
-(id)init
{
//[super init];
DBName = #"FoodDB2.sqlite";
NSArray* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDir = [documentsPath objectAtIndex:0];
DBPath = [documentsDir stringByAppendingPathComponent:DBName];
return self;
}
-(void)InsertDataRollNo:(NSString*)theName
{
[self CheckAndCreateDB];
sqlite3* database;
if(sqlite3_open([DBPath UTF8String], &database)== SQLITE_OK)
{
NSString* statement;
sqlite3_stmt* compliedStatement;
//statement = [[NSString alloc]initWithFormat:#"insert into Category(TheName)values('%d')",#"epa"];
statement = #"insert into Category(TheName)values('aaa')";
const char* sqlStatement = [statement UTF8String];
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compliedStatement, NULL) == SQLITE_OK)
{
if(SQLITE_DONE!=sqlite3_step(compliedStatement))
{
NSAssert1(0,#"Error by inserting '%s' ", sqlite3_errmsg(database));
}
else
{
NSAssert1(0,#"cool '%s' ", #"ope");
}
}
sqlite3_finalize(compliedStatement);
}
sqlite3_close(database);
}
-(void)CheckAndCreateDB
{
BOOL success;
NSFileManager* fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:DBPath];
if(success) return;
NSString* databasePathFromApp = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:DBName];
[fileManager copyItemAtPath:databasePathFromApp toPath:DBPath error:nil];
//[fileManager release];
}
I figure it out, actually I was not copying the sqlite file to iPhone project, running good now

Resources