NSString *cityInput = cityField.text;
NSString *code = #"";
NSString *query = #"SELECT code FROM country WHERE cityname = UPPER(?)";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String],-1, &statement, nil) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [cityInput UTF8String], -1, SQLITE_STATIC);
while(sqlite3_step(statement) == SQLITE_ROW) {
code = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
}
}
if(sqlite3_step(statement) != SQLITE_DONE){
NSLog(#"DB: query KO");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"ALERT" message:#"City not found" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
return;
}
sqlite3_close(database);
Two questions:
1) for get single row i must use while loop?
2) if there isn't result in the query how alert "city not found"
Obviously you will get the last row,,
code
should be an array u might declare it like this
NSMutableArray *code=[NSMutableArray array];
then in the while loop use
[code addobject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)]];
I hope this is clear enough:)
Using while gives you the last row and it is not needed. Add limit 1 clause to your query, or simply take the first row returned;
Decide whether to show alert by checking return code.
Maybe two answers,
1) No, just an if clause will do
2) Do an assignement and then run an if clause on it
int result = sqlite3_step(statement)
if (result == SQLITE_ROW){
//processline
}
else{
//show alert
}
Related
I have a data base, this is in my proyect how a file localDB.db I want update some information of a table in this since my aplication`s code the method I use is the follow:
-(void)establecePerfil:(int)idPerfil{
while ([Utilidades consultaCargandoDatosDB]) {
[NSThread sleepForTimeInterval:1.0];
}
[Utilidades cargandoDatos:YES];
//perfil = [Perfil getInstance];
[self cargarBaseDeDatos];
NSLog(#"entre en establecer perfik");
sqlite3 *dataBase;
sqlite3_stmt *sentencia;
if(sqlite3_open([self.dataBasePath UTF8String], &dataBase)==SQLITE_OK){
NSLog(#"entre en establecer perfik 2");
NSString *sql = [NSString stringWithFormat:#"UPDATE perfiles SET \"seleccionado\"= 1, \"completado\"=0 WHERE \"id\"= %d", idPerfil];
if(sqlite3_prepare_v2(dataBase, [sql UTF8String], -1, &sentencia, NULL)==SQLITE_OK){
sqlite3_reset(sentencia);
if(sqlite3_step(sentencia)==SQLITE_OK){
NSLog(#"set profile OK");
}
else{
// NSAssert1(0, #"Error while selecting. '%s'", sqlite3_errmsg(dataBase));
NSLog( #"Save Error: %s", sqlite3_errmsg(dataBase) );
NSLog(#"%i", sqlite3_extended_errcode(dataBase));
NSLog(#"%i",sqlite3_errcode(dataBase));
}
}
sqlite3_finalize(sentencia);
}else{
NSLog(#"No se ha abierto la base de datos");
}
sqlite3_close(dataBase);
[Utilidades cargandoDatos:NO];
}
I think, I have the problem in sqlite3_step(sentencia) because code error that appear after of else condition is 101 referencing to SQLITE_DONE so I don`t know that means this.
The documentation says that SQLITE_DONE is correct (and SQLITE_OK would not be).
I'm using FMDatabase to operate on an sqlite3 database. Here's my code:
NSString *dbFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:#"temp_info.db"]];
FMDatabase *fmdb = [FMDatabase databaseWithPath:dbFilePath];
if (![fmdb open]) {
NSLog(#"......");
} else {
NSString *sql = #"CREATE TABLE IF NOT EXISTS test1(id INTEGER, name TEXT, create_time TEXT)";
if (![fmdb executeUpdate:sql]) {
NSLog(#"......");
}
for (int i = 0; i < 3; i++) {
BOOL result = [fmdb executeUpdate:#"INSERT INTO test1(id, name, create_time) values(?,?,?)", i+1, #"test", #"12-09-10 12:10"];
NSLog(#"%d", result);
}
// EXC_BAD_ACCESS
}
When I run the line:
BOOL result = [fmdb executeUpdate:#"INSERT INTO test1(id, name, create_time) values(?,?,?)", i+1, #"test", #"12-09-10 12:10"];
I get an EXC_BAD_ACCESS error. Why?
question has been solved!
*1.*All arguments provided to the -executeUpdate: method(or any of the variants that accept a va_list as a parameter) must be objects.The following will be not work (and will result in a crash):
[db executeUpdate:#"INSERT INTO mytable VALUES (?)", 66];
The proper way to insert a number is to box it in an NSNumber object:
[db executeUpdate:#"INSERT INTO mytable VALUES (?)", [NSNumber numberWithInt:66]];
*2.*Alternatively,you can use the -execute*WithFormat: variant to use NSString-style substitution:
[db executeUpdateWithFormat:#"INSERT INTO mytable VALUES (%d)", 66];
Internally,the -execute*WithFormat: methods are properly boxing things for you.The following percent modifiers are recognized:%#,%c,%s,%d,%D,%i,%u,%U,%hi,%hu,%qi,%qu,%f,%ld,%lu,%lld,and %llu.Using a modifier other than those will have unpredictable results.If,for some reason,you need the % character to appear in your SQL statement,you should use %%.
Now I am trying to add a front end check on my app to detect if user input only number in the textfield.
I use:
- (IBAction)checkID:(UITextField *)sender {
if ([sender.text isEqualToString:#""]) {
sender.text = #"This information is required";
sender.backgroundColor =[UIColor redColor];
}else if (![sender.text intValue]) {
sender.text = [sender.text stringByAppendingString:#" is not valid number"];
sender.backgroundColor =[UIColor redColor];
}
NSLog(#"send.text is %#, intValue is %d",sender.text,[sender.text intValue]);
}
But I found it text begins with number and ends with string, its intValue is still the number.
In my text, text is "00001aa", but the intValue is 1.
Is there any other way to filter out this "00001aa" text?
Thanks in advance.
Yes, you can use NSRegularExpression, or NSCharacterSet (works for positive numbers).
For regular expressions, use ^[-+]?[0-9]+$.
NSRegularExpression *numEx = [NSRegularExpression
regularExpressionWithPattern:#"^[-+]?[0-9]+$" options:0 error:nil
];
NSLog(#"%ld", [numEx numberOfMatchesInString:#"-200" options:0 range:NSMakeRange(0, 4)]);
NSLog(#"%ld", [numEx numberOfMatchesInString:#"001A" options:0 range:NSMakeRange(0, 4)]);
For character set, use [NSCharacterSet decimalDigitCharacterSet].
BOOL isNum = [[NSCharacterSet decimalDigitCharacterSet]
isSupersetOfSet:[NSCharacterSet characterSetWithCharactersInString:#"001AA"]
];
I want to do mock for TnSettings, yes, it works if code by the following method, the problem is that we need to do write mock code for each case, if we only mock once then execute more than one case, then the second will report exception. I use the latest OCMock V2.01.
My question is that why OCMock has such restriction? Or is it my fault not to use it correctly?
Any idea or discussion will be appreciated, thanks in advance.
- (void) testFormattedDistanceValueWithMeters {
mockSettings = [OCMockObject mockForClass:[TnSettings class]];
mockClientModel = [TnClientModel createMockClientModel];
[[[mockClientModel expect] andReturn:mockSettings] settings];
[[[mockSettings expect] andReturn:[NSNumber numberWithInt:0]] preferencesGeneralUnits];
NSNumber *meters = [NSNumber numberWithDouble:0.9];
distance = [NSString formattedDistanceValueWithMeters:meters];
STAssertEqualObjects(distance, #"0.9", #"testformattedEndTimeForTimeInSeconds failed");
//------------- Another case -----------------
mockSettings = [OCMockObject mockForClass:[TnSettings class]];
mockClientModel = [TnClientModel createMockClientModel];
[[[mockClientModel expect] andReturn:mockSettings] settings];
[[[mockSettings expect] andReturn:[NSNumber numberWithInt:0]] preferencesGeneralUnits];
meters = [NSNumber numberWithDouble:100.9];
distance = [NSString formattedDistanceValueWithMeters:meters];
STAssertEqualObjects(distance, #"101", #"testformattedEndTimeForTimeInSeconds failed");
}
Not sure I understand your question or your code fully. I suspect that you stumbled over the difference between expect and stub, though.
Is this what you had in mind?
- (void) testFormattedDistanceValueWithMeters {
mockSettings = [OCMockObject mockForClass:[TnSettings class]];
mockClientModel = [TnClientModel createMockClientModel];
[[[mockClientModel stub] andReturn:mockSettings] settings];
[[[mockSettings stub] andReturn:[NSNumber numberWithInt:0]] preferencesGeneralUnits];
NSNumber *meters = [NSNumber numberWithDouble:0.9];
distance = [NSString formattedDistanceValueWithMeters:meters];
STAssertEqualObjects(distance, #"0.9", #"testformattedEndTimeForTimeInSeconds failed");
meters = [NSNumber numberWithDouble:100.9];
distance = [NSString formattedDistanceValueWithMeters:meters];
STAssertEqualObjects(distance, #"101", #"testformattedEndTimeForTimeInSeconds failed");
}
My eyes hurt from hours of trying to figure this one - and i have looked for an answer for quite a while on-line (it will be embarrassing to tell how much...).
all i am trying to do is to enumerate using a for-in loop on anExpression which is a NSMutableArray that holds NSNumbers and NSStrings.
my NSLog print for the variable ans returns an empty string.
What am i doing wrong?
NSString *ans = #"";
for (id obj in anExpression)
{
if ([obj isKindOfClass:[NSString class]])
[ans stringByAppendingString:(NSString *)obj];
if ([obj isKindOfClass:[NSNumber class]])
[ans stringByAppendingString:(NSString *)[obj stringValue]];
NSLog(#"String so far: %# ", ans);
}
I think you mean
ans = [ans stringByAppendingString:(NSString *)obj];
not just
[ans stringByAppendingString:(NSString *)obj];
NSStrings are immutable -- you can't append to them. -stringByAppendingString: returns a new string (which you could then assign to ans).
Alternatively, you might use an NSMutableString and the -appendString: method.
Hey, sorry for the bad coding format, posting it again ...
NSString *ans = #"";
for (id obj in anExpression)
{
if ([obj isKindOfClass:[NSString class]])
[ans stringByAppendingString:(NSString *)obj];
if ([obj isKindOfClass:[NSNumber class]])
[ans stringByAppendingString:(NSString *)[obj stringValue]];
NSLog(#"String so far: %# ", ans);
}
[ans autorelease];
NSLog(#"final string is: %# ", ans);
return ans;
the method stringByAppendingString: returns a new string made by appending the given string to the receiver.
so you want ans = [ans stringByAppendingString:obj];