How to set sslmode as allow in postgresql in Objective-C - objective-c

I used the following code to connect to the postgresql database. It works good. But now I want to connect it with sslmode enabled. Can anyone help me to acheive this.
NSString* portS = [NSNumber numberWithInteger:port].stringValue;
headerPG = PQsetdbLogin(serverName.UTF8String,portS.UTF8String,NULL,NULL,databaseName.UTF8String,
userName.UTF8String, password.UTF8String);
BOOL result = [self connected];
NSString *resultString;
if(!result){
//Error connection
[self errorPG];
resultString = #"Connection Failed";
}
else{
resultString = #"Connected Successfully";
}
return resultString;
I dont know how to use the following function.
PGconn *PQconnectdbParams(const char **keywords, const char **values, int expand_dbname);
How to feed data in keywords, values, etc.
Thanks in advance.

I got the answer myself.
const char *const keywords[] = {[#"sslmode" UTF8String], [#"hostaddr" UTF8String], [#"port" UTF8String], [#"user" UTF8String], [#"password" UTF8String], [#"dbname" UTF8String]};
const char *const values[] = {[#"allow" UTF8String], [serverName UTF8String], [portS UTF8String],[userName UTF8String],[password UTF8String],[databaseName UTF8String]};
headerPG = PQconnectdbParams(keywords, values, 1);
Here the keyword array has the keywords of postgresql and value array has the values of particular key in keyword array.

Related

How to read input in Objective-C?

I am trying to write some simple code that searches two dictionaries for a string and prints to the console if the string appears in both dictionaries. I want the user to be able to input the string via the console, and then pass the string as a variable into a message. I was wondering how I could go about getting a string from the console and using it as the argument in the following method call.
[x rangeOfString:"the string goes here" options:NSCaseInsensitiveSearch];
I am unsure as to how to get the string from the user. Do I use scanf(), or fgets(), into a char and then convert it into a NSSstring, or simply scan into an NSString itself. I am then wondering how to pass that string as an argument. Please help:
Here is the code I have so far. I know it is not succinct, but I just want to get the job done:
#import <Foundation/Foundation.h>
#include <stdio.h>
#include "stdlib.h"
int main(int argc, const char* argv[]){
#autoreleasepool {
char *name[100];
printf("Please enter the name you wish to search for");
scanf("%s", *name);
NSString *name2 = [NSString stringWithFormat:#"%s" , *name];
NSString *nameString = [NSString stringWithContentsOfFile:#"/usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL];
NSString *dictionary = [NSString stringWithContentsOfFile:#"/usr/share/dict/words" encoding:NSUTF8StringEncoding error:NULL];
NSArray *nameString2 = [nameString componentsSeparatedByString:#"\n"];
NSArray *dictionary2 = [dictionary componentsSeparatedByString:#"\n"];
int nsYES = 0;
int dictYES = 0;
for (NSString *n in nameString2) {
NSRange r = [n rangeOfString:name2 options:NSCaseInsensitiveSearch];
if (r.location != NSNotFound){
nsYES = 1;
}
}
for (NSString *x in dictionary2) {
NSRange l = [x rangeOfString:name2 options:NSCaseInsensitiveSearch];
if (l.location != NSNotFound){
dictYES = 1;
}
}
if (dictYES && nsYES){
NSLog(#"glen appears in both dictionaries");
}
}
}
Thanks.
Safely reading from standard input in an interactive manner in C is kind of involved. The standard functions require a fixed-size buffer, which means either some input will be too long (and corrupt your memory!) or you'll have to read in a loop. And unfortunately, Cocoa doesn't offer us a whole lot of help.
For reading standard input entirely (as in, if you're expecting an input file over standard input), there is NSFileHandle, which makes it pretty succinct. But for interactively reading and writing like you want to do here, you pretty much have to go with the linked answer for reading.
Once you have read some input into a C string, you can easily turn it into an NSString with, for example, +[NSString stringWithUTF8String:].

Use of undeclared identifier - identifier is in "if statement"

I have an alert Use of undeclared identifier 'sql3'.
If I delete the if statement, there 's no problem, but it seems it's not recognized when sql3 is inside the if statement.
Is there a way to fix it?
if ([typedepartie isEqual: #"ami"]) {
const char *sql3 =
[[NSString stringWithFormat:#"SELECT id
FROM tabledesquestions
WHERE pack = ? ORDER BY RANDOM() LIMIT 4"]
cStringUsingEncoding:NSUTF8StringEncoding];
}
listequestionmulti = [[NSMutableArray alloc]init];
sqlite3_stmt *sql1Statement;
if(sqlite3_prepare(database1, sql3, -1, &sql1Statement, NULL) != SQLITE_OK) {
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(database1));
}
The identifier sql3 is defined inside curly braces. Therefore it is purely local to those curly braces. Therefore when you get past that to the next part of your code, it no longer exists.
if ([typedepartie isEqual: #"ami"]) {
const char *sql3 = // sql3 is born here...;
} // and dies here
What you want is more like this:
char *sql3 = // default value;
if ([typedepartie isEqual: #"ami"]) {
sql3 = // other value;
}

Return strings in sequence from NSMutableArray [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have a NSMutableArray with comma separated strings for an objective-c iphone application (iOS SDK 6.0). I need a simple function that, when triggered, returns a string, one at a time, from string 0 onwards. To give you some context, a user would click a button, and for every click a new string is returned, in order, from the Array. It's a list of previously saved "favourite quotes". The string is displayed in a UITextView.
Ideally, I would also have a function for reversing, i.e. going backwards in the array from the current position.
This might be pretty basic, but I seem to only be able to find more advanced implementations that I'm unable to translate into this looping backwards and forwards in an Array of strings.
EDIT: Current code for this function below. I need to add the part where one string at a time is returned from the array (allRows) and displayed in a textview
- (IBAction)nextQoute:(id)sender {
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_qoutesDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT qoutesSaved FROM qoutes"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_qoutesDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
NSMutableArray *allRows = [[[NSMutableArray alloc] init] autorelease];
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *qouteField = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
NSString *str = [NSString stringWithFormat:#"%#", qouteField];
[allRows addObject:str];
[qouteField release];
}
Very thankful for help!
You mention that you are new to Objective C, and based on how I read what you're describing, I wonder if you are making this a lot more complicated than it needs to be. Items in an array (that is, NSArray, or NSMutableArray) aren't "seperated" by anything - different items in an array are accessed by their order in the array, called an index. So in your code, when you build allRows, each str that you put into it gets put into its own index, and to get it back out of the array, you just use that index.
For example, let's pretend your quotes you are pulling from your database are:
"Here's looking at you kid"
"I'll be back"
"It's a trap"
If they are put into the array in that order, and you want to put "It's a trap" into a textfield (called myTextField), you just write
myTextField.text = [allRows objectAtIndex:2];
In the end, that means what you probably want to do for your app is keep a counter you pass to objectAtIndex. When the user clicks the forward button, increase the count. When they click the back button, decrease the count. Then, call the code I put above, except instead of sending the value 2, send your counter variable. As mentioned in the comments to H2CO3s answer, make sure you put some validation in there to prevent your count from going beyond the limits of your array, or you'll get a nasty crash. If this is indeed what you are trying to do and you are still confused, I can add some more code.
I'm not too familiar with accessing a sqlite database the way you do here (I use CoreData, so the calls are very different), so perhaps I am completely mistaken about what you are trying to do here - but this seems like a very simple task that is being very overcomplicated.
You can just keep track of the string index in an instance variable (or if you don't have an object to work with because you write a class method or a function and not an instance method, then you can use a static local variable too).
#interface Foo: NSObject {
NSInteger index;
NSArray *strings;
}
// ...
- (NSString *)nextString
{
return index < strings.count ? strings[index++] : nil;
}
- (NSString *)previousString
{
return index > 0 ? strings[--index] : nil;
}
You can fetch the whole data in database.And store it one array
declare these two objects.
#interface YourClassName: NSObject {
NSInteger stringIndex;
NSArray *quoteFieldDataArr;
}
NSMutableArr *quoteFieldDataArr=[self fetchDataFromDataBase];
-(NSMutableDictionary *)fetchDataFromDataBase
{
const char *dbpath = [_databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &_qoutesDB) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:
#"SELECT qoutesSaved FROM qoutes"];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(_qoutesDB,
query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
NSMutableDictionary *allRows = [[[NSMutableDictionary alloc] init] autorelease];
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *qouteField = [[NSString alloc]
initWithUTF8String:
(const char *) sqlite3_column_text(
statement, 0)];
NSString *str = [NSString stringWithFormat:#"%#", qouteField];
[allRows addObject:str];
[qouteField release];
return nil;
}
// Load Next String
- (NSString *)loadNextString
{
return stringIndex < quoteFieldDataArr.count ? quoteFieldDataArr[stringIndex++] : nil;
}
- (NSString *)loadpreviousString
{
return stringIndex > 0 ? quoteFieldDataArr[--stringIndex] : nil;
}

Possibly bad memory access?

I am currently developing on Objective-C using sqlite3. The following code seems like a bad memory access.
-(sqlite3_stmt *)PrepareStmt:(NSString *)query
{
//...
const char *query_stmt = [query UTF8String];
sqlite3_stmt *stmt = nil;
int retval = 0;
if ((retval = sqlite3_prepare_v2(db, query_stmt, -1, &stmt, nil)) == SQLITE_OK)
{
return stmt;
}
else
{
//Error handling...
}
}
- (void)SomeFunc
{
NSString *query = #""; //Assume valid SQL statement
sqlite3_stmt *stmt = [self PrepareStmt:query];
//Use stmt, like step, etc.
sqlite3_finalize(stmt);
}
The sqlite3_stmt in PrepareStmt is set to nil and it will be an out parameter from sqlite3_prepare_v2(). The memory should be allocated in that function. Therefore, it should be released by calling sqlite3_finalize().
My question here is that if we return sqlite3_stmt from PrepareStmt(), it should be still valid right? The local pointer in PrepareStmt() is already popped off the stack, but the memory allocated by sqlite3_prepare_v2() should still be valid.
Is this thinking valid? Or do I need to pass in an address of an pointer to PrepareStmt()?
Thank you!
Yes it's valid in this case. But note that sqlite3_finalize() isn't just about releasing memory (i.e. dealloc). It also sends a message to the DB to tell it to drop it's precompiled SQL statement, etc...

Getting number of rows from SQLite C interface in Objective-C

I am new to objective-C and iphone apps.
I am accessing SQLite and have 3 rows in my table "coffee". I used the following way to grab sth out from the table, however, only then 2nd and 3rd rows are being pulled out {the 1st row is always missed}. Is that due to the logic in my while loop by checking while sqlite3_step(selectstmt) returns SQLITE_ROW is wrong? Here is the code:
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "select coffeeID, coffeeName from coffee";
sqlite3_stmt *selectstmt;
NSLog(#"sqlite_prepare_v2 returns: %i", sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL));
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
NSLog(#"sqlite3_step returns: %i", sqlite3_step(selectstmt));
while(sqlite3_step(selectstmt) == SQLITE_ROW) {
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];
coffeeObj.coffeeName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
NSLog(#"this is the coffee name: %#", coffeeObj.coffeeName);
coffeeObj.isDirty = NO;
[appDelegate.coffeeArray addObject:coffeeObj];
[coffeeObj release];
}
}
}
On the other hand, is there any convenient way for me to check the number of rows returen in a query directly from the C interface of SQLite?
Many thanks.
You could use the query SELECT COUNT(*) FROM coffee to tell you how many rows there are.
And also, save yourself some headaches and use a SQLite wrapper.
Are the 2 sqlite3_step() calls meant to be executed here?
NSLog(#"sqlite3_step returns: %i", sqlite3_step(selectstmt));
while(sqlite3_step(selectstmt) == SQLITE_ROW {
BTW: there a parenthesis missing in the while line. Do not rewrite your code for SO. Copy/Paste it to avoid copying errors (pasting errors are much more rare)