<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Karl Kraft &#187; MySQL</title>
	<atom:link href="http://www.karlkraft.com/index.php/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.karlkraft.com</link>
	<description>Just a 2 bit programmer in a 64 bit world</description>
	<lastBuildDate>Thu, 24 Jun 2010 14:20:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mysql and Objective-C</title>
		<link>http://www.karlkraft.com/index.php/2010/06/02/mysql-and-objective-c/</link>
		<comments>http://www.karlkraft.com/index.php/2010/06/02/mysql-and-objective-c/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 02:02:15 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/?p=137</guid>
		<description><![CDATA[In honor of Objective-C becoming a top-ten language, I&#8217;ve decided to share a library of source code I created to access MySQL. Over the past 2 years I&#8217;ve worked on a small bit of glue to make selects, updates, inserts and deletes work easily from Objective-C.  This includes support for converting MySQL types to Cocoa [...]]]></description>
			<content:encoded><![CDATA[<p>In honor of <a href="http://apple.slashdot.org/story/10/06/02/1930209/Objective-C-Enters-Top-Ten-In-Language-Popularity">Objective-C becoming a top-ten language</a>, I&#8217;ve decided to share a library of source code I created to access MySQL.</p>
<p><span id="more-137"></span>
<p>Over the past 2 years I&#8217;ve worked on a small bit of glue to make selects, updates, inserts and deletes work easily from Objective-C.  This includes support for converting MySQL types to Cocoa types, working correctly with garbage collection, and support for reading and writing large blobs.</p>
<p>It is possible to do all these things with the generic MySQL C connector, and if your needs are simple that can be a quick way to access a MySQL databases, since all C libraries can easily be called from Objective-C.  However, once you start dealing with more advanced topics, the C connector can become burdensome.</p>
<p>If you are working on intel platforms only, you should grab the intel only version.  This supports both 32 and 64 bit intel platforms, using version 6.0.2 of the MySQL C Connector.</p>
<p><a href="http://www.karlkraft.com/wp-content/uploads/2010/06/ObjC_mysql_intel.zip">ObjC_mysql_intel.zip﻿</a> 5.5 MB &#8211; 32/64 bit</p>
<p>I still have some client programs running on PPC boxes, but MySQL has dropped support for PPC based OSX﻿ in the most recent versions of the mysql_connector.  So I have an older version that I occasionally update, although not as often as the intel only version.  This version uses an older version (5.0.51a) of the MySQL C connector, and supports both 32 bit PPC and Intel platforms.</p>
<p><a title="ObjC_mysql_ppc.zip" href="http://www.karlkraft.com/wp-content/uploads/2010/06/ObjC_mysql_ppc.zip">ObjC_mysql_ppc.zip</a> ﻿2.3 MB &#8211; 32 bit intel and PPC.</p>
<p>Both versions use an identical syntax and are for the most part interchangeable.</p>
<p>﻿Both require that garbage collection be enabled in your application.  This means this version won&#8217;t support versions of iPhone OS that don&#8217;t include garbage collection. Which is pretty much all of them, as of the writing of this post.</p>
<p>Both include the headers and a static library for the MySQL C connector.</p>
<p>While I have used these libraries to process well over half a billion rows of MySQL data, they are not by any means guaranteed to be free of bugs.  The most recent fix was a leak in MysqlUpdate.  If you are interested in getting updates, subscribe to the <a href="http://www.karlkraft.com/index.php/category/mysql/feed/">MySQL Category Feed</a>, or <a href="mailto:karl@karlkraft.com?subject=MySQL SVN Access Request">email me</a> for access to the subversion repository for the project.</p>
<h1 style="font-size: 2em;">Adding to Your Project</h1>
<p>Once you have extracted the zip, add everything inside to your project.  The static mysql library will be linked into your application, and the headers and all the necessary bits to compile should just fall into place.</p>
<h3>Forming the connection</h3>
<p>You connect by creating an instance of MysqlConnection.  The best method for starting is</p>
<p> </p>
<pre>+ (MysqlConnection *)connectToHost:(NSString *)host
                              user:(NSString *)user
                          password:(NSString *)password
                            schema:(NSString *)schema
                             flags:(unsigned long)flags;
</pre>
<p>The best option for flags is MYSQL_DEFAULT_CONNECTION_FLAGS﻿</p>
<p>If you are connecting to a MySQL server that will kick you if inactive, call the method</p>
<pre>-[MysqlConnection startIdle]</pre>
<p>to start a low impact periodic select that will run once every 60 seconds.  Four additional methods add support for transactions</p>
<h3>Performing Selects</h3>
<p>Selects are pretty straight forward. Use MysqlFetch, and pass a SQL select command.  You can then look at the results property to get an array of dictionaries.  Each dictionary represents a single row.  They key will be the name of each column, and the value will be the Objective-C type that matches the column. If you aren&#8217;t sure of the names of the fields, you can look at the fields an fieldNames properties for more details.</p>
<pre>Example:
MysqlConnection *connection = [MysqlConnection connectToHost:@"serverName"
                                                        user:@"aUserName"
                                                    password:@"aPassword"
                                                      schema:@"myForumName"
                                                       flags:MYSQL_DEFAULT_CONNECTION_FLAGS];
MysqlFetch *userFetch = [MysqlFetch fetchWithCommand:@"select U_Number,U_Username from w3t_Users"
                                        onConnection:connection];
QLog(@"There are %d members",[userFetch.results count]);
for (NSDictionary *userRow in userFetch.results) {
  NSNumber *userNumber = [userRow objectForKey:@"U_Number"];
  NSString *userName = [userRow objectForKey:U_Username"];
  NSLog("%@ %@",userNumber,userName);
}
</pre>
<h3>Performing Deletes</h3>
<p>Deletes, inserts, and updates are very similar.  To perform a delete:</p>
<pre>
MysqlDelete *deleteCommand = [MysqlDelete deleteWithConnection:connection];
delete.tableName=@"w3t_Users";
delete.qualifier=[NSDictionary dictionaryWithObject:@"3" andKey:@"U_Number"];
[deleteCommand execute];
</pre>
<p>You can then look at the affectedRows property to find out how many rows were deleted.</p>
<h3>Performing Inserts</h3>
<p>Inserts allow you to insert NSString, NSNumber, NSData, and NSNull.  All other classes are converted using their -description method.  The insert code uses bindings instead of composing a SQL string, so you don&#8217;t need to worry about escaping special characters, or filtering user input.</p>
<pre>
MysqlInsert *insertCommand = [MysqlInsert insertWithConnection:connection];
insertCommand.table =@"w3t_Users";
NSData *picture = [NSData dataWithContentsOfFile:@"sample.png"];
NSString *password=@";'!#";
insertCommand.rowData=[NSDictionary dictionaryWithObjectsAndKeys:@"Karl Kraft",@"U_Username",
                                                          picture,@"U_UserImage"
                                                          password,@"UserPassword"
                                                          nil];
[insertCommand execute];
</pre>
<p>After the insert, you can get the auto increment rowid by using the rowid property on your MysqlInsert instance.</p>
<h3>Performing Updates</h3>
<p>Once you have mastered delete and insert, updates are a simple cross of the two.  Specify a qualifier, like you would for deletion, but rowData like you would use for an insert.  Only the specified fields in the rowData are modified.  Again you can pass NSString, NSNumber, NSData, and NSNull, and the values are inserted using bindings so that you don&#8217;t need to provide odd escapes.
<pre>
MysqlUpdate *updateCommand = [MysqlInsert insertWithConnection:connection];
updateCommand.table =@"w3t_Users";
updateCommand.qualifier=[NSDictionary dictionaryWithObject:@"3" andKey:@"U_Number"];
NSData *picture = [NSData dataWithContentsOfFile:@"sample.png"];
NSString *password=@";'!#";
updateCommand.rowData=[NSDictionary dictionaryWithObjectsAndKeys:@"Karl Kraft",@"U_Username",
                                                          picture,@"U_UserImage"
                                                          password,@"UserPassword"
                                                          nil];
[updateCommand execute];
</pre>
<p>Like delete you can query the affectedRows property to find out how many records were updated.</p>
<h3>Catching exceptions</h3>
<p>Any exceptions while performing the mysql commands are thrown as MysqlException or a subclass of MysqlException.  Common reasons for exceptions being throw are:</p>
<ul>
<li>Unable to connect to the database, or wrong username / password
<li>Commit or rollback fails
<li>Unsupported field type in a MysqlFetch
<li>Unqualified delete or update commands
<li>Any underlying mysql error
</ul>
<h3>MYSQL_LOGGING</h3>
<p>As a final useful trick you can define MYSQL_LOGGING in the CFLAGS of your project, or in a common header file, and useful debugging information will be generated.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2010/06/02/mysql-and-objective-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
