SlideShare uma empresa Scribd logo
1 de 70
Baixar para ler offline
SQLitePersistentObjects



Tuesday, March 3, 2009
SQLite Without the SQL
                         Jeff LaMarche




Tuesday, March 3, 2009
Contacting Me
                    • jeff_lamarche@mac.com
                    • http://iphonedevelopment.blogspot.com
                    • Twitter: jeff_lamarche




Tuesday, March 3, 2009
About Me
                    • Writer
                     • Beginning iPhone Development (Apress)
                     • Several Articles for ADC & MacTech Mag
                     • Beginning Cocoa (Apress, in progress)
                     • Regular blog postings


Tuesday, March 3, 2009
More About Me
                    • Programmer
                     • Primarily contract work
                     • Using Cocoa since about 2000
                     • OO Programming since early 1990s
                     • Programming since 1980
                     • Full-time with Cocoa for only a year

Tuesday, March 3, 2009
Image Source: http://www.macgeek.org/museum/bhapple2plus/page02.html




Tuesday, March 3, 2009
Tuesday, March 3, 2009
Enough About Me
                             (yeah, seriously)




Tuesday, March 3, 2009
SQLPO
                                    SQLitePersistentObjects

                • Object-Relational Mapping (ORM) Tool
                         or for the more technically-minded:

                         code that takes data from your program and
                         sticks it into or pulls it out of a relational
                         database




Tuesday, March 3, 2009
In the Beginning...
                   • Early OO programs that needed to use data
                         from a database embedded SQL statements
                         in code
                         • Difficult to maintain
                         • Strings are a “black box” to the compiler


Tuesday, March 3, 2009
ORM History
                   • 1996 Enterprise Object Frameworks (EOF)
                    • Part of NeXT’s Cocoa-Based WebObjects
                    • Used visual tool to map data objects to
                           database table
                         • Once model created, you interacted with
                           database tables as if they were objects
                         • Didn’t even have to create specific classes
                           if you didn’t want to
Tuesday, March 3, 2009
ORM History
                   • Basic idea was borrowed by other platforms,
                         changed to work with other languages,
                         sometimes extended to be better
                         • Hibernate, Cayenne, ADO .net, Outlet,
                           Django, many others




Tuesday, March 3, 2009
ORM History
                   • One language evolved the concept
                    • Ruby on Rails’ ActiveRecord
                      • No longer needed mapping document
                      • Object structure dynamically created
                         based on table structure in database




Tuesday, March 3, 2009
ORM History
                   • Core Data
                    • Core Data on the Mac is EOF’s stepchild
                    • Core Data is NOT EOF, but shares some
                         DNA




Tuesday, March 3, 2009
ORM History
                         Apple has not ported Core Data to the
                         iPhone (yet).


                         That fact is what triggered the birth of
                         SQLitePersistentObjects




Tuesday, March 3, 2009
SQLPO
                                       SQLitePersistentObjects

                • You can always find the latest version here:
                         http://code.google.com/p/sqlitepersistentobjects/
                • Add the code from the /src directory to your
                         Xcode project
                • Make sure to link to the SQLite3 dynamic library
                         at /usr/lib/libsqlite3.dylib




Tuesday, March 3, 2009
SQLPO
                                    SQLitePersistentObjects

          •       We have a support mailing list:
                  http://groups.google.com/group/sqlitepersistentobjects-user


          • Licensed under the New BSD License
             • Free, open source.
             • No attribution required, non-viral, can be used in
                         commercial projects, no need to publish your code
                     • If you can’t use BSD licensed code for some reason,
                         contact me - we’re flexible on the license.
Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        To create a persistent object, you simply subclass
                         an existing class.
                               #import <Foundation/Foundation.h>
                               #import quot;SQLitePersistentObject.hquot;

                               @interface Person : SQLitePersistentObject
                               {
                               	 NSString	    *firstName;
                               	 NSString	    *lastName;
                               	 NSDate	 	    *birthdate;
                               	 int	 	   	   numberOfChildren;
                               	 float	   	   contribution;
                               	 UIImage	 	   *photo;
                               }
                               @property (nonatomic, retain) NSString *firstName;
                               @property (nonatomic, retain) NSString *lastName;
                               @property (nonatomic, retain) NSDate *birthdate;
                               @property int numberOfChildren;
                               @property float contribution;
                               @property (nonatomic, retain) UIImage *photo;
                               @end


Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        To create a persistent object, you simply subclass
                         an existing class.
                               #import <Foundation/Foundation.h>
                               #import quot;SQLitePersistentObject.hquot;

                               @interface Person : SQLitePersistentObject
                               {
                               	 NSString	    *firstName;
                               	 NSString	    *lastName;
                               	 NSDate	 	    *birthdate;
                               	 int	 	   	   numberOfChildren;
                               	 float	   	   contribution;
                               	 UIImage	 	   *photo;
                               }
                               @property (nonatomic, retain) NSString *firstName;
                               @property (nonatomic, retain) NSString *lastName;
                               @property (nonatomic, retain) NSDate *birthdate;
                               @property int numberOfChildren;
                               @property float contribution;
                               @property (nonatomic, retain) UIImage *photo;
                               @end


Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        To create a persistent object, you simply subclass
                         an existing class.
                               #import quot;Person.hquot;

                               @implementation Person
                               @synthesize firstName;
                               @synthesize lastName;
                               @synthesize birthdate;
                               @synthesize numberOfChildren;
                               @synthesize contribution;
                               @synthesize photo;
                               - (void)dealloc
                               {
                               	 [firstName release];
                               	 [lastName release];
                               	 [birthdate release];
                               	 [photo release];
                               	 [super dealloc];
                               }
                               @end



Tuesday, March 3, 2009
The Basics
                                           SQLitePersistentObjects


                •        Once you’ve defined a persistent object, creating a
                         new object and saving it to the database couldn’t
                         be easier:

                          	   Person *newPerson = [[Person alloc] init];
                          	   newPerson.firstName = @quot;Marthaquot;;
                          	   newPerson.lastName = @quot;Washingtonquot;;
                          	   newPerson.birthdate = [NSDate date];
                          	   newPerson.numberOfChildren = 5;
                          	   newPerson.contribution = 27.32;
                          	   newPerson.photo = [UIImage imageNamed:@quot;MarthaWashington.pngquot;];
                          	   [newPerson save];
                          	   [newPerson release];




Tuesday, March 3, 2009
The Basics
                                           SQLitePersistentObjects


                •        Once you’ve defined a persistent object, creating a
                         new object and saving it to the database couldn’t
                         be easier:

                          	   Person *newPerson = [[Person alloc] init];
                          	   newPerson.firstName = @quot;Marthaquot;;
                          	   newPerson.lastName = @quot;Washingtonquot;;
                          	   newPerson.birthdate = [NSDate date];
                          	   newPerson.numberOfChildren = 5;
                          	   newPerson.contribution = 27.32;
                          	   newPerson.photo = [UIImage imageNamed:@quot;MarthaWashington.pngquot;];
                          	   [newPerson save];
                          	   [newPerson release];




Tuesday, March 3, 2009
The Basics
                                      SQLitePersistentObjects


                •        How does it save the data?

                         •   Raw datatypes are mapped to appropriate
                             columns

                             •   e.g. int goes into INTEGER field, float goes
                                 into REAL field

                         •   Other persistent objects are stored as
                             references to the row and table where that
                             object is stored


Tuesday, March 3, 2009
The Basics
                                       SQLitePersistentObjects


                •        How does it save the data? (cont)

                         •   Objects that aren’t subclasses of
                             SQLitePersistentObject get stored IF they
                             conform to a protocol called SQLitePersistence

                         •   We have provided categories for most common
                             objects to conform them to SQLitePersistence
                             •   NSString, NSNumber, UIImage, UIColor, NSData,
                                 NSDate, NSMutableData



Tuesday, March 3, 2009
The Basics
                                     SQLitePersistentObjects


                •        How does it save the data? (cont)

                            •   We also provide category on NSObject as a
                                fallback. Any object that doesn’t conform to
                                SQLitePersistence but that does conform to
                                NSCoding can be stored in the database, but
                                gets archived as a BLOB, which can’t be
                                searched or used in criteria-based queries.




Tuesday, March 3, 2009
The Basics
                                      SQLitePersistentObjects


                •        How does it save the data? (cont)

                         •   Dictionaries, Arrays, and Sets do not get stored
                             in a column in the object’s table, but rather get
                             stored in a child table.

                             •   Each item in collection gets one row in the
                                 child table

                             •   Raw Datatypes and non-persistent objects get
                                 stored right in child table

                             •   Persistent objects get stored as references
Tuesday, March 3, 2009
The Basics
                                     SQLitePersistentObjects


                •        How does it save the data? (cont)

                         •   Every objects gets assigned a primary key value,
                             which is an integer that acts as a unique
                             identifier for that object

                         •   Stored in a private instance variable called pk

                         •   Used in some cases load objects from database




Tuesday, March 3, 2009
The Basics
                                         SQLitePersistentObjects


                •        Loading an object from the database is
                         accomplished through class methods. This is the
                         simplest one:
                             	 Person *martha = [Person findByPK:1];




Tuesday, March 3, 2009
The Basics
                                         SQLitePersistentObjects


                •        You can load all objects into an array. Be careful
                         doing this, however, as it is not a very efficient use
                         of memory in most cases.
                             	 NSArray *people = [Person allObjects];




Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects


                •        SQLPO also creates dynamic find methods based
                         on your property names:


                            	 NSArray *people = [Person allObjects];




                            	 NSArray *people = [Person findByLastName:@quot;Washingtonquot;];




Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects


                •        Dynamic find by methods support SQL wildcards



                            	 NSArray *people = [Person allObjects];




                            	 NSArray *people = [Person findByLastName:@quot;Washingtonquot;];




                            	 NSArray *people = [Person findByLastName:@quot;Wash%quot;];




Tuesday, March 3, 2009
The Basics
                                      SQLitePersistentObjects
                         #import <Foundation/Foundation.h>
                         #import quot;SQLitePersistentObject.hquot;

                         @interface Person : SQLitePersistentObject
                         {
                         	 NSString	      *firstName;
                         	 NSString	      *lastName;
                         	 NSDate	    	   *birthdate;
                         	 int	 	     	   numberOfChildren;
                         	 float		        contribution;
                         	 UIImage	 	     *photo;
                         }
                         @property (nonatomic, retain) NSString *firstName;
                         @property (nonatomic, retain) NSString *lastName;
                         @property (nonatomic, retain) NSDate *birthdate;
                         @property int numberOfChildren;
                         @property float contribution;
                         @property (nonatomic, retain) UIImage *photo;
                         @end

                         @interface Person (squelch)
                         + (id)findByName:(NSString *)theName;
                         @end




Tuesday, March 3, 2009
The Basics
                                      SQLitePersistentObjects
                         #import <Foundation/Foundation.h>
                         #import quot;SQLitePersistentObject.hquot;

                         @interface Person : SQLitePersistentObject
                         {
                         	 NSString	      *firstName;
                         	 NSString	      *lastName;
                         	 NSDate	    	   *birthdate;
                         	 int	 	     	   numberOfChildren;
                         	 float		        contribution;
                         	 UIImage	 	     *photo;
                         }
                         @property (nonatomic, retain) NSString *firstName;
                         @property (nonatomic, retain) NSString *lastName;
                         @property (nonatomic, retain) NSDate *birthdate;
                         @property int numberOfChildren;
                         @property float contribution;
                         @property (nonatomic, retain) UIImage *photo;
                         @end

                         @interface Person (squelch)
                         + (id)findByName:(NSString *)theName;
                         @end




Tuesday, March 3, 2009
The Basics
                                               SQLitePersistentObjects


                •        If you need more flexibility, you can always specify
                         the exact criteria by supplying a SQL where clause
                         with findByCriteria:
                         	 NSArray *people = [Person findByCriteria:@quot;WHERE first_name = 'John' and last_name like
                         'S%' and date(birthdate) <= date('now')quot;];




Tuesday, March 3, 2009
The Basics
                                               SQLitePersistentObjects


                •        If you need more flexibility, you can always specify
                         the exact criteria by supplying a SQL where clause
                         with findByCriteria:
                         	 NSArray *people = [Person findByCriteria:@quot;WHERE first_name = 'John' and last_name like
                         'S%' and date(birthdate) <= date('now')quot;];




                                       Note: Property firstName
                                             becomes column first_name



Tuesday, March 3, 2009
The Basics
                                           SQLitePersistentObjects


                •        You can find out the column name for a property
                         name like so:



                           #import quot;NSString-SQLiteColumnName.hquot;
                           …
                           NSString *columnName = [@quot;firstNamequot; stringAsSQLColumnName];




Tuesday, March 3, 2009
The Basics
                                             SQLitePersistentObjects


                •        If you only want the first object that meets your
                         criteria, you can do that also:



                             Person *firstPerson = [Person findFirstByCriteria:@quot;WHERE first_name =
                         'John' and last_name like 'S%' and date(birthdate) <= date('now')quot;];




Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects


                •        Deleting an object should be done using the class
                         method deleteObject:cascade:, which takes the
                         primary key of the object to be deleted.


                               [Person deleteObject:5 cascade:YES];




Tuesday, March 3, 2009
The Basics
                                           SQLitePersistentObjects


                •        Database tables can benefit from adding indices to
                         them. SQLitePersistentObjects has a mechanism
                         for adding indices without writing SQL. Override
                         this method in your class:

                           +(NSArray *)indices
                           {
                           	   return nil;
                           }




Tuesday, March 3, 2009
The Basics
                                           SQLitePersistentObjects


                •        Method should return an array of arrays. Each
                         contained array represents one index and should
                         have the properties to be indexed in the order
                         they should be in the index.

                           +(NSArray *)indices
                           {
                           	   NSArray *firstIndex = [NSArray arrayWithObjects:@quot;lastNamequot;,
                           @quot;firstNamequot;, @quot;pkquot;, nil];
                           	   NSArray *secondIndex = [NSArray arrayWithObjects:@quot;birthdatequot;, @quot;pkquot;,
                           nil];
                           	   return [NSArray arrayWithObjects:firstIndex, secondIndex, nil];
                           }




Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        Let’s look at our class declaration again.

                               #import <Foundation/Foundation.h>
                               #import quot;SQLitePersistentObject.hquot;

                               @interface Person : SQLitePersistentObject
                               {
                               	 NSString	    *firstName;
                               	 NSString	    *lastName;
                               	 NSDate	 	    *birthdate;
                               	 int	 	   	   numberOfChildren;
                               	 float	   	   contribution;
                               	 UIImage	 	   *photo;
                               }
                               @property (nonatomic, retain) NSString *firstName;
                               @property (nonatomic, retain) NSString *lastName;
                               @property (nonatomic, retain) NSDate *birthdate;
                               @property int numberOfChildren;
                               @property float contribution;
                               @property (nonatomic, retain) UIImage *photo;
                               @end


Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        Let’s look at our class declaration again.

                               #import <Foundation/Foundation.h>
                               #import quot;SQLitePersistentObject.hquot;

                               @interface Person : SQLitePersistentObject
                               {
                               	 NSString	    *firstName;
                               	 NSString	    *lastName;
                               	 NSDate	 	    *birthdate;
                               	 int	 	   	   numberOfChildren;
                               	 float	   	   contribution;
                               	 UIImage	 	   *photo;
                               }
                               @property (nonatomic, retain) NSString *firstName;
                               @property (nonatomic, retain) NSString *lastName;
                               @property (nonatomic, retain) NSDate *birthdate;
                               @property int numberOfChildren;
                               @property float contribution;
                               @property (nonatomic, retain) UIImage *photo;
                               @end


Tuesday, March 3, 2009
The Basics
                                     SQLitePersistentObjects

                •        Let’s look at our class declaration again.




Tuesday, March 3, 2009
The Basics
                                        SQLitePersistentObjects

                •        Let’s talk about Paired Arrays.

                          •   Simple Concept - Multiple Arrays

                          •   Every array has same number of rows

                          •   Object at same index in each array
                              corresponds to information about the same
                              object

                              •   e.g. fifth object in one array might hold Joe’s
                                  age, and the fifth object in the other array
                                  might hold Joe’s last name.

Tuesday, March 3, 2009
The Basics
                                      SQLitePersistentObjects

                •        Let’s talk about Paired Arrays (cont)

                •        Can have as many arrays as necessary.

                •        SQLPO has built-in method to return specified
                         paired arrays.

                •        It packs all the paired arrays together inside
                         another array

                •        First array in the array always contains a list of the
                         primary keys.


Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Martha            Washington
                          2                 Joe               Smith
                          3                Sally               Ride
                          4               George            Washington
                          5               Buster             Keaton




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Martha            Washington
                          2                 Joe               Smith
                          3                Sally               Ride
                          4               George            Washington
                          5               Buster             Keaton




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Martha            Washington
                          2                 Joe               Smith
                          3                Sally               Ride
                          4               George            Washington
                          5               Buster             Keaton




Tuesday, March 3, 2009
The Basics
                                     SQLitePersistentObjects

                •        This means we can load in only the information we
                         need to display in the table, along with the
                         information we need to load the full object if the
                         user selects it.




Tuesday, March 3, 2009
The Basics
                                         SQLitePersistentObjects

                •        In our controller class, we’ll need mutable arrays to
                         hold the data.
                               #import <UIKit/UIKit.h>

                               @interface PeopleListViewController : UITableViewController
                               {
                               	 NSMutableArray	 *pks;
                               	 NSMutableArray	 *firstNames;
                               	 NSMutableArray	 *lastNames;
                               }
                               @property (nonatomic, retain) NSMutableArray *pks;
                               @property (nonatomic, retain) NSMutableArray *firstNames;
                               @property (nonatomic, retain) NSMutableArray *lastNames;
                               - (void)refreshData;
                               @end




                •        We also declare a method for loading the arrays.

Tuesday, March 3, 2009
The Basics
                                          SQLitePersistentObjects

                •        Getting the paired arrays is simple enough:
                   - (void)refreshData
                   {
                   	 NSArray *array = [Person pairedArraysForProperties:[NSArray
                   arrayWithObjects:@quot;firstNamequot;, @quot;lastNamequot;, nil] withCriteria:@quot;where birthdate is not
                   nullquot;];
                   	 self.pks = [array objectAtIndex:0];
                   	 self.firstNames = [array objectAtIndex:1];
                   	 self.lastNames = [array objectAtIndex:2];
                   }



                •        Just tell it which properties you want, and it will
                         give you all those plus the primary keys.




Tuesday, March 3, 2009
The Basics
                                          SQLitePersistentObjects

                •        In our Table View Data Source, we just get a count
                         of one of the arrays so we know the number of
                         rows we need in our table:
                   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
                   (NSInteger)section
                   {
                       return [pks count];
                   }




Tuesday, March 3, 2009
The Basics
                                         SQLitePersistentObjects

                 •       We can then use the information from the arrays
                         to populate our table:
             - (UITableViewCell *)tableView:(UITableView *)tableView
             		       cellForRowAtIndexPath:(NSIndexPath *)indexPath
             {
                 static NSString *CellIdentifier = @quot;Cellquot;;

                   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
                   if (cell == nil)
             	     {
                       cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
             	   	     	   	   	    	   	   	   	      reuseIdentifier:CellIdentifier] autorelease];
                   }
             	     NSUInteger row = [indexPath row];
                   cell.text = [NSString stringWithFormat:@quot;%@, %@quot;,
             	   	     	   	     [lastNames objectAtIndex:row],
             	   	     	   	     [firstNames objectAtIndex:row]];

                   return cell;
             }




Tuesday, March 3, 2009
The Basics
                                         SQLitePersistentObjects

                •        When the user selects a row, we grab the primary
                         key for the selected row, and use that to load the
                         Person:

                  - (void)tableView:(UITableView *)tableView
                  didSelectRowAtIndexPath:(NSIndexPath *)indexPath
                  {
                  	 int	 thePk = [[pks objectAtIndex:[indexPath row]] intValue];
                  	 Person *thePerson = (Person *)[Person findByPK:thePk];
                  	 // Do something with the person here...
                  }




Tuesday, March 3, 2009
The Basics
                             SQLitePersistentObjects

                         Easy Enough, but there’s a problem.


                         What if you want to sort the arrays?




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Martha            Washington
                          2                 Joe               Smith
                          3                Sally               Ride
                          4               George            Washington
                          5               Buster             Keaton




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Buster             Keaton
                          2               George               Ride
                          3                 Joe               Smith
                          4               Martha            Washington
                          5                Sally            Washington




Tuesday, March 3, 2009
The Basics
                                            SQLitePersistentObjects

                • Categories to the Rescue!
                • Just call sortArrayUsingSelector:withPairedMutableArrays:
                            	   [lastNames sortArrayUsingSelector:@selector(compare:)
                            	   	    	     withPairedMutableArrays:firstNames, pks, nil];




                • Now all three arrays are sorted based on the last
                         name of the people represented in the arrays.




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          1               Martha            Washington
                          2                 Joe               Smith
                          3                Sally               Ride
                          4               George            Washington
                          5               Buster             Keaton




Tuesday, March 3, 2009
The Basics
                                  SQLitePersistentObjects

                               Example: Three NSArrays
                         pks           firstNames            lastNames
                          5               Buster             Keaton
                          4               George            Washington
                          2                 Joe               Smith
                          1               Martha            Washington
                          3                Sally               Ride




Tuesday, March 3, 2009
The Not-So-Basics
                                              SQLitePersistentObjects

                • SQLite makes aggregations easy (if you know SQL)

                 double averageAge = [Person performSQLAggregation:
                 @quot;select avg(date('now') - date(birthdate)) from people where birthdate is not nullquot;];




Tuesday, March 3, 2009
The Not-So-Basics
                                                  SQLitePersistentObjects

                • But, if you don’t know SQL… you’re not totally out
                         of luck. SQLPO creates dynamic methods for
                         common aggregations based on your objects’
                         properties:

     	   NSNumber        *average = [Person averageOfContribution];
     	   NSNumber        *washAverage = [Person averageOfContributionWithCriteria:@quot;where name = 'Washington'quot;];
     	   NSNumber        *sum = [Person sumOfContribution];
     	   NSNumber        *washSum = [Person sumOfContributionWithCriteria:@quot;where name = 'Washington'quot;];
     	   NSNumber        *count = [Person countOfPk];
     	   NSNumber        *min = [Person minOfContribution];
     	   NSNumber        *washMin = [Person minOfContributionWithCriteria:@quot;where name = 'Washington'quot;];
     	   NSNumber        *max = [Person maxOfContribution];
     	   NSNumber        *washMax = [Person maxOfContributionWithCriteria:@quot;where name = 'Washington'quot;];




Tuesday, March 3, 2009
The Not-So-Basics
                                             SQLitePersistentObjects

                • Defining how non-standard, non-persistent objects
                         get stored.

                         @protocol SQLitePersistence
                         @required
                         + (BOOL)canBeStoredInSQLite;
                         + (NSString *)columnTypeForObjectStorage;
                         + (BOOL)shouldBeStoredInBlob;
                         @optional
                         + (id)objectWithSqlColumnRepresentation:(NSString *)columnData;
                         - (NSData *)sqlBlobRepresentationOfSelf;
                         + (id)objectWithSQLBlobRepresentation:(NSData *)data;
                         - (NSString *)sqlColumnRepresentationOfSelf;
                         @end




Tuesday, March 3, 2009
The Not-So-Basics
                                        SQLitePersistentObjects

                • The Instance Manager
                • SQLPO has a singleton class that manages the
                         database instance.
                • Mostly, this class is used behind-the-scenes without
                         any need for you to interact with it.
                • But... it’s there if you need it.




Tuesday, March 3, 2009
The Not-So-Basics
                                                  SQLitePersistentObjects

                • Getting the shared instance:
                         SQLiteInstanceManager *manager = [SQLiteInstanceManager sharedManager];




Tuesday, March 3, 2009
The Not-So-Basics
                                     SQLitePersistentObjects

                • Once you have it, what can you do with it?

                • Get a reference to the database
                                   sqlite3 *db = [manager database];



                • Execute arbitrary SQL Updates:
                          [manager executeUpdateSQL:@quot;update foo set bar = 1quot;];




Tuesday, March 3, 2009
The Not-So-Basics
                                       SQLitePersistentObjects

                • Once you have it, what can you do with it? (cont)

                • Find out if a table exists in the database.
                           	   BOOL exists = [manager tableExists:@quot;superheroesquot;];




                • Change database configuration and do maintenance
                           	   [manager vacuum];
                           	   [manager setCacheSize:100]




Tuesday, March 3, 2009
Performance
                                         SQLitePersistentObjects

                • What Lies Ahead
                         • validation architecture & willSave/didSave/okayToSave:
                         • transient properties
                         • performance optimizations
                         • rollback
                         • refactoring to generalize code where makes sense
                         • ??? (ideas welcome)



Tuesday, March 3, 2009
Performance
                                SQLitePersistentObjects

                • How well does it perform?
                   • Umm... good question.
                   • Can we get back to you on that?




Tuesday, March 3, 2009
SQLitePersistentObjects




                              Questions?



Tuesday, March 3, 2009

Mais conteúdo relacionado

Semelhante a Using SQLite

Lecture 10 slides (february 4, 2010)
Lecture 10 slides (february 4, 2010)Lecture 10 slides (february 4, 2010)
Lecture 10 slides (february 4, 2010)
Bruce Lee
 
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMFBuilding RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Kenn Hussey
 
2011 codestrong-abstracting-databases-access-in-titanium-mobile
2011 codestrong-abstracting-databases-access-in-titanium-mobile2011 codestrong-abstracting-databases-access-in-titanium-mobile
2011 codestrong-abstracting-databases-access-in-titanium-mobile
Axway Appcelerator
 
Никита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-CНикита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-C
DataArt
 

Semelhante a Using SQLite (20)

Objective-C A Beginner's Dive
Objective-C A Beginner's DiveObjective-C A Beginner's Dive
Objective-C A Beginner's Dive
 
Introduction to MVC in iPhone Development
Introduction to MVC in iPhone DevelopmentIntroduction to MVC in iPhone Development
Introduction to MVC in iPhone Development
 
Memory Deduction Games
Memory Deduction GamesMemory Deduction Games
Memory Deduction Games
 
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
 
Advanced Action Script
Advanced Action ScriptAdvanced Action Script
Advanced Action Script
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Connecting to a REST API in iOS
Connecting to a REST API in iOSConnecting to a REST API in iOS
Connecting to a REST API in iOS
 
Lecture 10 slides (february 4, 2010)
Lecture 10 slides (february 4, 2010)Lecture 10 slides (february 4, 2010)
Lecture 10 slides (february 4, 2010)
 
Becoming Indie
Becoming IndieBecoming Indie
Becoming Indie
 
Invokedynamic: Tales from the Trenches
Invokedynamic: Tales from the TrenchesInvokedynamic: Tales from the Trenches
Invokedynamic: Tales from the Trenches
 
Becoming Indie
Becoming IndieBecoming Indie
Becoming Indie
 
I phone udvikling best brains
I phone udvikling best brainsI phone udvikling best brains
I phone udvikling best brains
 
03 objective-c session 3
03  objective-c session 303  objective-c session 3
03 objective-c session 3
 
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMFBuilding RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
 
MacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meet
 
2011 codestrong-abstracting-databases-access-in-titanium-mobile
2011 codestrong-abstracting-databases-access-in-titanium-mobile2011 codestrong-abstracting-databases-access-in-titanium-mobile
2011 codestrong-abstracting-databases-access-in-titanium-mobile
 
Abstracting databases access in Titanium Mobile
Abstracting databases access in Titanium MobileAbstracting databases access in Titanium Mobile
Abstracting databases access in Titanium Mobile
 
jQuery Mobile, Backbone.js, and ASP.NET MVC
jQuery Mobile, Backbone.js, and ASP.NET MVCjQuery Mobile, Backbone.js, and ASP.NET MVC
jQuery Mobile, Backbone.js, and ASP.NET MVC
 
Extending Spring for Custom Usage
Extending Spring for Custom UsageExtending Spring for Custom Usage
Extending Spring for Custom Usage
 
Никита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-CНикита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-C
 

Mais de John Wilker

Mais de John Wilker (20)

Cranking Floating Point Performance Up To 11
Cranking Floating Point Performance Up To 11Cranking Floating Point Performance Up To 11
Cranking Floating Point Performance Up To 11
 
Introtoduction to cocos2d
Introtoduction to  cocos2dIntrotoduction to  cocos2d
Introtoduction to cocos2d
 
Getting Started with OpenGL ES
Getting Started with OpenGL ESGetting Started with OpenGL ES
Getting Started with OpenGL ES
 
User Input in a multi-touch, accelerometer, location aware world.
User Input in a multi-touch, accelerometer, location aware world.User Input in a multi-touch, accelerometer, location aware world.
User Input in a multi-touch, accelerometer, location aware world.
 
Physics Solutions for Innovative Game Design
Physics Solutions for Innovative Game DesignPhysics Solutions for Innovative Game Design
Physics Solutions for Innovative Game Design
 
Getting Oriented with MapKit: Everything you need to get started with the new...
Getting Oriented with MapKit: Everything you need to get started with the new...Getting Oriented with MapKit: Everything you need to get started with the new...
Getting Oriented with MapKit: Everything you need to get started with the new...
 
Getting Started with iPhone Game Development
Getting Started with iPhone Game DevelopmentGetting Started with iPhone Game Development
Getting Started with iPhone Game Development
 
Internationalizing Your Apps
Internationalizing Your AppsInternationalizing Your Apps
Internationalizing Your Apps
 
Optimizing Data Caching for iPhone Application Responsiveness
Optimizing Data Caching for iPhone Application ResponsivenessOptimizing Data Caching for iPhone Application Responsiveness
Optimizing Data Caching for iPhone Application Responsiveness
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Integrating Push Notifications in your iPhone application with iLime
Integrating Push Notifications in your iPhone application with iLimeIntegrating Push Notifications in your iPhone application with iLime
Integrating Push Notifications in your iPhone application with iLime
 
Starting Core Animation
Starting Core AnimationStarting Core Animation
Starting Core Animation
 
P2P Multiplayer Gaming
P2P Multiplayer GamingP2P Multiplayer Gaming
P2P Multiplayer Gaming
 
Using Concurrency To Improve Responsiveness
Using Concurrency To Improve ResponsivenessUsing Concurrency To Improve Responsiveness
Using Concurrency To Improve Responsiveness
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
Mobile WebKit Development and jQTouch
Mobile WebKit Development and jQTouchMobile WebKit Development and jQTouch
Mobile WebKit Development and jQTouch
 
Accelerometer and OpenGL
Accelerometer and OpenGLAccelerometer and OpenGL
Accelerometer and OpenGL
 
Deep Geek Diving into the iPhone OS and Framework
Deep Geek Diving into the iPhone OS and FrameworkDeep Geek Diving into the iPhone OS and Framework
Deep Geek Diving into the iPhone OS and Framework
 
NSNotificationCenter vs. AppDelegate
NSNotificationCenter vs. AppDelegateNSNotificationCenter vs. AppDelegate
NSNotificationCenter vs. AppDelegate
 
From Flash to iPhone
From Flash to iPhoneFrom Flash to iPhone
From Flash to iPhone
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Último (20)

WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 

Using SQLite

  • 2. SQLite Without the SQL Jeff LaMarche Tuesday, March 3, 2009
  • 3. Contacting Me • jeff_lamarche@mac.com • http://iphonedevelopment.blogspot.com • Twitter: jeff_lamarche Tuesday, March 3, 2009
  • 4. About Me • Writer • Beginning iPhone Development (Apress) • Several Articles for ADC & MacTech Mag • Beginning Cocoa (Apress, in progress) • Regular blog postings Tuesday, March 3, 2009
  • 5. More About Me • Programmer • Primarily contract work • Using Cocoa since about 2000 • OO Programming since early 1990s • Programming since 1980 • Full-time with Cocoa for only a year Tuesday, March 3, 2009
  • 8. Enough About Me (yeah, seriously) Tuesday, March 3, 2009
  • 9. SQLPO SQLitePersistentObjects • Object-Relational Mapping (ORM) Tool or for the more technically-minded: code that takes data from your program and sticks it into or pulls it out of a relational database Tuesday, March 3, 2009
  • 10. In the Beginning... • Early OO programs that needed to use data from a database embedded SQL statements in code • Difficult to maintain • Strings are a “black box” to the compiler Tuesday, March 3, 2009
  • 11. ORM History • 1996 Enterprise Object Frameworks (EOF) • Part of NeXT’s Cocoa-Based WebObjects • Used visual tool to map data objects to database table • Once model created, you interacted with database tables as if they were objects • Didn’t even have to create specific classes if you didn’t want to Tuesday, March 3, 2009
  • 12. ORM History • Basic idea was borrowed by other platforms, changed to work with other languages, sometimes extended to be better • Hibernate, Cayenne, ADO .net, Outlet, Django, many others Tuesday, March 3, 2009
  • 13. ORM History • One language evolved the concept • Ruby on Rails’ ActiveRecord • No longer needed mapping document • Object structure dynamically created based on table structure in database Tuesday, March 3, 2009
  • 14. ORM History • Core Data • Core Data on the Mac is EOF’s stepchild • Core Data is NOT EOF, but shares some DNA Tuesday, March 3, 2009
  • 15. ORM History Apple has not ported Core Data to the iPhone (yet). That fact is what triggered the birth of SQLitePersistentObjects Tuesday, March 3, 2009
  • 16. SQLPO SQLitePersistentObjects • You can always find the latest version here: http://code.google.com/p/sqlitepersistentobjects/ • Add the code from the /src directory to your Xcode project • Make sure to link to the SQLite3 dynamic library at /usr/lib/libsqlite3.dylib Tuesday, March 3, 2009
  • 17. SQLPO SQLitePersistentObjects • We have a support mailing list: http://groups.google.com/group/sqlitepersistentobjects-user • Licensed under the New BSD License • Free, open source. • No attribution required, non-viral, can be used in commercial projects, no need to publish your code • If you can’t use BSD licensed code for some reason, contact me - we’re flexible on the license. Tuesday, March 3, 2009
  • 18. The Basics SQLitePersistentObjects • To create a persistent object, you simply subclass an existing class. #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end Tuesday, March 3, 2009
  • 19. The Basics SQLitePersistentObjects • To create a persistent object, you simply subclass an existing class. #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end Tuesday, March 3, 2009
  • 20. The Basics SQLitePersistentObjects • To create a persistent object, you simply subclass an existing class. #import quot;Person.hquot; @implementation Person @synthesize firstName; @synthesize lastName; @synthesize birthdate; @synthesize numberOfChildren; @synthesize contribution; @synthesize photo; - (void)dealloc { [firstName release]; [lastName release]; [birthdate release]; [photo release]; [super dealloc]; } @end Tuesday, March 3, 2009
  • 21. The Basics SQLitePersistentObjects • Once you’ve defined a persistent object, creating a new object and saving it to the database couldn’t be easier: Person *newPerson = [[Person alloc] init]; newPerson.firstName = @quot;Marthaquot;; newPerson.lastName = @quot;Washingtonquot;; newPerson.birthdate = [NSDate date]; newPerson.numberOfChildren = 5; newPerson.contribution = 27.32; newPerson.photo = [UIImage imageNamed:@quot;MarthaWashington.pngquot;]; [newPerson save]; [newPerson release]; Tuesday, March 3, 2009
  • 22. The Basics SQLitePersistentObjects • Once you’ve defined a persistent object, creating a new object and saving it to the database couldn’t be easier: Person *newPerson = [[Person alloc] init]; newPerson.firstName = @quot;Marthaquot;; newPerson.lastName = @quot;Washingtonquot;; newPerson.birthdate = [NSDate date]; newPerson.numberOfChildren = 5; newPerson.contribution = 27.32; newPerson.photo = [UIImage imageNamed:@quot;MarthaWashington.pngquot;]; [newPerson save]; [newPerson release]; Tuesday, March 3, 2009
  • 23. The Basics SQLitePersistentObjects • How does it save the data? • Raw datatypes are mapped to appropriate columns • e.g. int goes into INTEGER field, float goes into REAL field • Other persistent objects are stored as references to the row and table where that object is stored Tuesday, March 3, 2009
  • 24. The Basics SQLitePersistentObjects • How does it save the data? (cont) • Objects that aren’t subclasses of SQLitePersistentObject get stored IF they conform to a protocol called SQLitePersistence • We have provided categories for most common objects to conform them to SQLitePersistence • NSString, NSNumber, UIImage, UIColor, NSData, NSDate, NSMutableData Tuesday, March 3, 2009
  • 25. The Basics SQLitePersistentObjects • How does it save the data? (cont) • We also provide category on NSObject as a fallback. Any object that doesn’t conform to SQLitePersistence but that does conform to NSCoding can be stored in the database, but gets archived as a BLOB, which can’t be searched or used in criteria-based queries. Tuesday, March 3, 2009
  • 26. The Basics SQLitePersistentObjects • How does it save the data? (cont) • Dictionaries, Arrays, and Sets do not get stored in a column in the object’s table, but rather get stored in a child table. • Each item in collection gets one row in the child table • Raw Datatypes and non-persistent objects get stored right in child table • Persistent objects get stored as references Tuesday, March 3, 2009
  • 27. The Basics SQLitePersistentObjects • How does it save the data? (cont) • Every objects gets assigned a primary key value, which is an integer that acts as a unique identifier for that object • Stored in a private instance variable called pk • Used in some cases load objects from database Tuesday, March 3, 2009
  • 28. The Basics SQLitePersistentObjects • Loading an object from the database is accomplished through class methods. This is the simplest one: Person *martha = [Person findByPK:1]; Tuesday, March 3, 2009
  • 29. The Basics SQLitePersistentObjects • You can load all objects into an array. Be careful doing this, however, as it is not a very efficient use of memory in most cases. NSArray *people = [Person allObjects]; Tuesday, March 3, 2009
  • 30. The Basics SQLitePersistentObjects • SQLPO also creates dynamic find methods based on your property names: NSArray *people = [Person allObjects]; NSArray *people = [Person findByLastName:@quot;Washingtonquot;]; Tuesday, March 3, 2009
  • 31. The Basics SQLitePersistentObjects • Dynamic find by methods support SQL wildcards NSArray *people = [Person allObjects]; NSArray *people = [Person findByLastName:@quot;Washingtonquot;]; NSArray *people = [Person findByLastName:@quot;Wash%quot;]; Tuesday, March 3, 2009
  • 32. The Basics SQLitePersistentObjects #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end @interface Person (squelch) + (id)findByName:(NSString *)theName; @end Tuesday, March 3, 2009
  • 33. The Basics SQLitePersistentObjects #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end @interface Person (squelch) + (id)findByName:(NSString *)theName; @end Tuesday, March 3, 2009
  • 34. The Basics SQLitePersistentObjects • If you need more flexibility, you can always specify the exact criteria by supplying a SQL where clause with findByCriteria: NSArray *people = [Person findByCriteria:@quot;WHERE first_name = 'John' and last_name like 'S%' and date(birthdate) <= date('now')quot;]; Tuesday, March 3, 2009
  • 35. The Basics SQLitePersistentObjects • If you need more flexibility, you can always specify the exact criteria by supplying a SQL where clause with findByCriteria: NSArray *people = [Person findByCriteria:@quot;WHERE first_name = 'John' and last_name like 'S%' and date(birthdate) <= date('now')quot;]; Note: Property firstName becomes column first_name Tuesday, March 3, 2009
  • 36. The Basics SQLitePersistentObjects • You can find out the column name for a property name like so: #import quot;NSString-SQLiteColumnName.hquot; … NSString *columnName = [@quot;firstNamequot; stringAsSQLColumnName]; Tuesday, March 3, 2009
  • 37. The Basics SQLitePersistentObjects • If you only want the first object that meets your criteria, you can do that also: Person *firstPerson = [Person findFirstByCriteria:@quot;WHERE first_name = 'John' and last_name like 'S%' and date(birthdate) <= date('now')quot;]; Tuesday, March 3, 2009
  • 38. The Basics SQLitePersistentObjects • Deleting an object should be done using the class method deleteObject:cascade:, which takes the primary key of the object to be deleted. [Person deleteObject:5 cascade:YES]; Tuesday, March 3, 2009
  • 39. The Basics SQLitePersistentObjects • Database tables can benefit from adding indices to them. SQLitePersistentObjects has a mechanism for adding indices without writing SQL. Override this method in your class: +(NSArray *)indices { return nil; } Tuesday, March 3, 2009
  • 40. The Basics SQLitePersistentObjects • Method should return an array of arrays. Each contained array represents one index and should have the properties to be indexed in the order they should be in the index. +(NSArray *)indices { NSArray *firstIndex = [NSArray arrayWithObjects:@quot;lastNamequot;, @quot;firstNamequot;, @quot;pkquot;, nil]; NSArray *secondIndex = [NSArray arrayWithObjects:@quot;birthdatequot;, @quot;pkquot;, nil]; return [NSArray arrayWithObjects:firstIndex, secondIndex, nil]; } Tuesday, March 3, 2009
  • 41. The Basics SQLitePersistentObjects • Let’s look at our class declaration again. #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end Tuesday, March 3, 2009
  • 42. The Basics SQLitePersistentObjects • Let’s look at our class declaration again. #import <Foundation/Foundation.h> #import quot;SQLitePersistentObject.hquot; @interface Person : SQLitePersistentObject { NSString *firstName; NSString *lastName; NSDate *birthdate; int numberOfChildren; float contribution; UIImage *photo; } @property (nonatomic, retain) NSString *firstName; @property (nonatomic, retain) NSString *lastName; @property (nonatomic, retain) NSDate *birthdate; @property int numberOfChildren; @property float contribution; @property (nonatomic, retain) UIImage *photo; @end Tuesday, March 3, 2009
  • 43. The Basics SQLitePersistentObjects • Let’s look at our class declaration again. Tuesday, March 3, 2009
  • 44. The Basics SQLitePersistentObjects • Let’s talk about Paired Arrays. • Simple Concept - Multiple Arrays • Every array has same number of rows • Object at same index in each array corresponds to information about the same object • e.g. fifth object in one array might hold Joe’s age, and the fifth object in the other array might hold Joe’s last name. Tuesday, March 3, 2009
  • 45. The Basics SQLitePersistentObjects • Let’s talk about Paired Arrays (cont) • Can have as many arrays as necessary. • SQLPO has built-in method to return specified paired arrays. • It packs all the paired arrays together inside another array • First array in the array always contains a list of the primary keys. Tuesday, March 3, 2009
  • 46. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Martha Washington 2 Joe Smith 3 Sally Ride 4 George Washington 5 Buster Keaton Tuesday, March 3, 2009
  • 47. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Martha Washington 2 Joe Smith 3 Sally Ride 4 George Washington 5 Buster Keaton Tuesday, March 3, 2009
  • 48. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Martha Washington 2 Joe Smith 3 Sally Ride 4 George Washington 5 Buster Keaton Tuesday, March 3, 2009
  • 49. The Basics SQLitePersistentObjects • This means we can load in only the information we need to display in the table, along with the information we need to load the full object if the user selects it. Tuesday, March 3, 2009
  • 50. The Basics SQLitePersistentObjects • In our controller class, we’ll need mutable arrays to hold the data. #import <UIKit/UIKit.h> @interface PeopleListViewController : UITableViewController { NSMutableArray *pks; NSMutableArray *firstNames; NSMutableArray *lastNames; } @property (nonatomic, retain) NSMutableArray *pks; @property (nonatomic, retain) NSMutableArray *firstNames; @property (nonatomic, retain) NSMutableArray *lastNames; - (void)refreshData; @end • We also declare a method for loading the arrays. Tuesday, March 3, 2009
  • 51. The Basics SQLitePersistentObjects • Getting the paired arrays is simple enough: - (void)refreshData { NSArray *array = [Person pairedArraysForProperties:[NSArray arrayWithObjects:@quot;firstNamequot;, @quot;lastNamequot;, nil] withCriteria:@quot;where birthdate is not nullquot;]; self.pks = [array objectAtIndex:0]; self.firstNames = [array objectAtIndex:1]; self.lastNames = [array objectAtIndex:2]; } • Just tell it which properties you want, and it will give you all those plus the primary keys. Tuesday, March 3, 2009
  • 52. The Basics SQLitePersistentObjects • In our Table View Data Source, we just get a count of one of the arrays so we know the number of rows we need in our table: - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section { return [pks count]; } Tuesday, March 3, 2009
  • 53. The Basics SQLitePersistentObjects • We can then use the information from the arrays to populate our table: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @quot;Cellquot;; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } NSUInteger row = [indexPath row]; cell.text = [NSString stringWithFormat:@quot;%@, %@quot;, [lastNames objectAtIndex:row], [firstNames objectAtIndex:row]]; return cell; } Tuesday, March 3, 2009
  • 54. The Basics SQLitePersistentObjects • When the user selects a row, we grab the primary key for the selected row, and use that to load the Person: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { int thePk = [[pks objectAtIndex:[indexPath row]] intValue]; Person *thePerson = (Person *)[Person findByPK:thePk]; // Do something with the person here... } Tuesday, March 3, 2009
  • 55. The Basics SQLitePersistentObjects Easy Enough, but there’s a problem. What if you want to sort the arrays? Tuesday, March 3, 2009
  • 56. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Martha Washington 2 Joe Smith 3 Sally Ride 4 George Washington 5 Buster Keaton Tuesday, March 3, 2009
  • 57. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Buster Keaton 2 George Ride 3 Joe Smith 4 Martha Washington 5 Sally Washington Tuesday, March 3, 2009
  • 58. The Basics SQLitePersistentObjects • Categories to the Rescue! • Just call sortArrayUsingSelector:withPairedMutableArrays: [lastNames sortArrayUsingSelector:@selector(compare:) withPairedMutableArrays:firstNames, pks, nil]; • Now all three arrays are sorted based on the last name of the people represented in the arrays. Tuesday, March 3, 2009
  • 59. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 1 Martha Washington 2 Joe Smith 3 Sally Ride 4 George Washington 5 Buster Keaton Tuesday, March 3, 2009
  • 60. The Basics SQLitePersistentObjects Example: Three NSArrays pks firstNames lastNames 5 Buster Keaton 4 George Washington 2 Joe Smith 1 Martha Washington 3 Sally Ride Tuesday, March 3, 2009
  • 61. The Not-So-Basics SQLitePersistentObjects • SQLite makes aggregations easy (if you know SQL) double averageAge = [Person performSQLAggregation: @quot;select avg(date('now') - date(birthdate)) from people where birthdate is not nullquot;]; Tuesday, March 3, 2009
  • 62. The Not-So-Basics SQLitePersistentObjects • But, if you don’t know SQL… you’re not totally out of luck. SQLPO creates dynamic methods for common aggregations based on your objects’ properties: NSNumber *average = [Person averageOfContribution]; NSNumber *washAverage = [Person averageOfContributionWithCriteria:@quot;where name = 'Washington'quot;]; NSNumber *sum = [Person sumOfContribution]; NSNumber *washSum = [Person sumOfContributionWithCriteria:@quot;where name = 'Washington'quot;]; NSNumber *count = [Person countOfPk]; NSNumber *min = [Person minOfContribution]; NSNumber *washMin = [Person minOfContributionWithCriteria:@quot;where name = 'Washington'quot;]; NSNumber *max = [Person maxOfContribution]; NSNumber *washMax = [Person maxOfContributionWithCriteria:@quot;where name = 'Washington'quot;]; Tuesday, March 3, 2009
  • 63. The Not-So-Basics SQLitePersistentObjects • Defining how non-standard, non-persistent objects get stored. @protocol SQLitePersistence @required + (BOOL)canBeStoredInSQLite; + (NSString *)columnTypeForObjectStorage; + (BOOL)shouldBeStoredInBlob; @optional + (id)objectWithSqlColumnRepresentation:(NSString *)columnData; - (NSData *)sqlBlobRepresentationOfSelf; + (id)objectWithSQLBlobRepresentation:(NSData *)data; - (NSString *)sqlColumnRepresentationOfSelf; @end Tuesday, March 3, 2009
  • 64. The Not-So-Basics SQLitePersistentObjects • The Instance Manager • SQLPO has a singleton class that manages the database instance. • Mostly, this class is used behind-the-scenes without any need for you to interact with it. • But... it’s there if you need it. Tuesday, March 3, 2009
  • 65. The Not-So-Basics SQLitePersistentObjects • Getting the shared instance: SQLiteInstanceManager *manager = [SQLiteInstanceManager sharedManager]; Tuesday, March 3, 2009
  • 66. The Not-So-Basics SQLitePersistentObjects • Once you have it, what can you do with it? • Get a reference to the database sqlite3 *db = [manager database]; • Execute arbitrary SQL Updates: [manager executeUpdateSQL:@quot;update foo set bar = 1quot;]; Tuesday, March 3, 2009
  • 67. The Not-So-Basics SQLitePersistentObjects • Once you have it, what can you do with it? (cont) • Find out if a table exists in the database. BOOL exists = [manager tableExists:@quot;superheroesquot;]; • Change database configuration and do maintenance [manager vacuum]; [manager setCacheSize:100] Tuesday, March 3, 2009
  • 68. Performance SQLitePersistentObjects • What Lies Ahead • validation architecture & willSave/didSave/okayToSave: • transient properties • performance optimizations • rollback • refactoring to generalize code where makes sense • ??? (ideas welcome) Tuesday, March 3, 2009
  • 69. Performance SQLitePersistentObjects • How well does it perform? • Umm... good question. • Can we get back to you on that? Tuesday, March 3, 2009
  • 70. SQLitePersistentObjects Questions? Tuesday, March 3, 2009