ObjectiveC sqlite3 issue - iphone

I'm finding that I have an issue when updating/inserting into my table in my iPhone app because I have a TEXT column, and when that text includes a ' symbol, things get messed up. What is the best way to handle this?
Should I check before I use a string that has an apostrophe? Is there a quick way to add formatting that will add an escape character in front of each apostrophe?
Does this question even make sense? lol.

sqlite requires the ' symbol to be escape by two ''.
Look at this from the official sqlite FAQ:
(14) How do I use a string literal that contains an embedded single-quote (') character?
The SQL standard specifies that single-quotes in strings are escaped by putting two single quotes in a row. SQL works like the Pascal programming language in the regard. SQLite follows this standard. Example:
INSERT INTO xyz VALUES('5 O''clock');

hey forget all this stuff. If you want your db to contain ' . Just replace your string with %27 & when fetching it back convert it back . You will get what you want. Check below :
// while Inserting into db
str = [str stringByReplacingOccurrencesOfString:#"'" withString:#"%27"];
// while fetching it back
text = [text stringByReplacingOccurrencesOfString:#"%27" withString:#"'"];
Enjoy programming :) :)

There's three ways to solve this:
Do the formatting yourself. Don't do this. (Well, not unless this string is part of your code rather than user input. In that case, this approach is fine.)
Use sqlite3_mprintf("%Q") to have SQLite do this. (%q does quote replacement; %Q does quote replacement and inserts NULL for a null pointer.)
Use bindings in your statement that you fill in with sqlite3_bind_text. This is the best way to do this, since it doesn't require recompiling the statement for every string and doesn't open you to SQL Injection.
Using a binding would look like this:
sqlite3_prepare(db, "INSERT INTO Table(Column) VALUES(?);", -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, [str cStringUsingEncoding:NSUTF8StringEncoding],
-1, SQLITE_TRANSIENT);
// stepping, etc
(Don't forget to do error checking.)

There is a function provided with SQLite that can escape characters as needed. Take a look at:
sqlite3_mprintf
http://www.sqlite.org/c3ref/mprintf.html

Related

Is there any way to prevent or detect char(0) from texts?

In some occasions, specially when copy-pasting, we end up having some text fields with a character 0 (nul) at the end of a string.
It doesn't show in any way when you display the data, but you do detect it when you export it.
We've tried to (at least) detect it by using the "Position" function.
However Position(text_field, char(0), 1, 1) won't find this char (it does return 0, even if the character is there).
I guess this is some kind of bug from FileMaker, but I'd like to know if anyone has found a way to circumvent it...
More info and a database sample at: https://community.claris.com/en/s/question/0D53w00005wrUMMCA2/character-0-0x0-in-text-fields
Unfortunately, the result of Char(0) is an empty string, not the expected control character.
You can generate the null character in a number of ways:
HexDecode ( "00" )
Base64Decode ( "AA==" )
ExecuteSQL ( "SELECT DISTINCT CHR(0) FROM SomeTable" ; "" ; "" )
or paste it into a global field and get it from there.
Once you have the character, it's easy to detect it or just substitute it out.
You may want to bypass the entire issue by allowing only printable characters - see, for example: https://www.briandunning.com/cf/1291
I run into this problem quite frequently when users try to copy-paste text from office programs into FileMaker fields on windows (my guess is that FileMaker for some reason can't handle Microsoft Office line endings properly).
The most efficient solution I found is to use auto enter calculation or script with Filter() function, in order to remove any unwanted characters.
Alterntively if you have access to plug-ins you can try using the MBS ("Text.RemoveControlCharacters") function from Monkeybread FileMaker plug-in which is uspposed to remove all characters with code 32 or lower.

Replace characters with multi-character strings

I am trying to replace German and Dutch umlauts such as ä, ü, or ß. They should be written like ae instead of ä. So I can't simply translate one char with another.
Is there a more elegant way to do that? Actually it looks like that (not completed yet):
SELECT addr, REPLACE (REPLACE(addr, 'ü','ue'),'ß','ss') FROM search;
On my way trying different commands I got another problem:
When I searched for Ü I got this:
ERROR: invalid byte sequence for encoding "UTF8": 0xdc27
Tried it with U&'\0220', it didn't replace anything. Only by using ü (for lowercase ü) it was replaced correctly. Has to do something with unicode, but how to solve this issue?
Kind regards from Germany. :)
Your server encoding seems to be UTF8.
I suspect your client_encoding does not match, which might give you a wrong impression of what you are dealing with. Check with:
SHOW client_encoding; -- in your actual session
And read this related answers:
Can not insert German characters in Postgres
Replace unicode characters in PostgreSQL
The rest of the tool chain has to be in sync, too. When using puTTY, for instance, one has to make sure, the terminal agrees with the rest: Change settings... Window -> Translation -> Remote character set = UTF-8.
As for your first question, you already have the best solution. A couple of umlauts are best replaced with a string of replace() statements.
As you seem to know already as well, single character replacements are more efficient with (a single) translate() statement.
Related:
Replace unicode characters in PostgreSQL
Regex remove all occurrences of multiple characters in a string
Beside other reasons I decided to write the replacement in python. Like Erwin wrote before, it seems there is no better solution as combining replace- commands.
In general pretty simple, even no encoding had to benn used. My "final" solution now looks like this:
ger_UE="Ü"
ger_AE="Ä"
ger_OE="Ö"
ger_SS="ß"
dk_AA="Å"
dk_OE="Ø"
dk_AE="Æ"
cur.execute("""Select addr, REPLACE (REPLACE (REPLACE( REPLACE (REPLACE (REPLACE (REPLACE(addr, '%s','UE'),'%s','OE'),'%s','AE'),'%s','SS'),'%s','AA'),'%s','OE'),'%s','AE')
from search WHERE x = '1';"""%(ger_UE,ger_OE,ger_AE,ger_SS,dk_AA,dk_OE,dk_AE))
I am now looking forward to the speed when it hits the large table. If anyone would like to make some annotations, they are very welcome.

iPhone - Using SQLite3: I'm trying to put into an sql table text that a user inputs (could be any characters). How to do it safely?

I know how to put text into a sqlite3 table in objective c. This is how I'm doing it:
NSString *sql = [NSString stringWithFormat: #"INSERT OR REPLACE INTO myTable (name, response) VALUES ('%#','%#');", name, response];
char *err;
if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK)
{
sqlite3_close(db);
}
My big concern is that since the text I'm putting into the table is coming directly from the user, it could contain any characters, including things like apostrophes, which would need to be escaped before being put into the table.
I have two main questions:
Besides apostrophes, what other characters do I need to escape for sql text that a user might enter?
What is the best way to alter the NSString to put in escapes before the characters that need to be escaped, before putting it into the sql table? Should I just use a scanner and parse the string character by character searching for characters that should be escaped?
Thanks!
You should use the built in ? feature. You will need to create prepared statement, then use sqlite_3_bind_text.
"INSERT OR REPLACE INTO myTable (name, response) VALUES (?,?);"
I would also recommend looking into FMDB.
Have you considered using Core Data? It should take care of these things automatically.

Whats an alternative to having to use sqlite prepared statements to escape characters

I'm working on an iPhone app, which uses the SQLite database, and I'm trying to handle escape characters. I know that there is LIKE ESCAPE to handle escape characters in select statements, but in my application i have SELECT, INSERT, UPDATE actions and i really don't know how to go about handling escape characters.
if you are using sqlite3_exec() all-in-one function,
you dont need to use sqlite3_bind* functions..
just pass the string to sqlite3_mprintf() with %q token
sqlite3_mprintf("%q","it's example");
and the output string is
it''s example
Use FMDB, and then you won't have to. It has built-in parameter binding support, and that will take care of any escaping you need for you.
I believe you simply have to tell SQLite what your escape character is at the end of the SQL statement. For example:
SELECT * FROM MyTable WHERE RevenueChange LIKE '%0\%' ESCAPE '\'
The LIKE will match values such as 30%, 140%, etc. The character I used, \, could be anything.

Adding a newline to a UITextView

I've been searching for an answer to this question on google and some other forums, but I haven't found the answer yet. It seems like a simple enough question: how do I manually insert a newline into UITextView's text field?
If it matters, I'm reading my string from an SQLite database. That means that I'm translating a const char (I think - at least I've been casting it as such) into an NSString before I use it in UITextView's -setText. I've tried inserting '\n' into the SQLite database, but after everything is translated and assigned it comes back as '\n' on the iPhone screen. Is there another character I can use?
Escape sequences in strings are interpreted at compile time and replaced with their actual byte value - therefore they have no meaning outside of the compiler.
Passing the string as it came out of your database to [UITextView setText:] is all you need to do. Your database should be holding line breaks as-is (0x0A).
Andrew