<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CreaterOS</title>
    <description>The latest articles on DEV Community by CreaterOS (@createros).</description>
    <link>https://dev.to/createros</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F633183%2Fd049b286-4c27-4d87-95d2-5f8129a00b1c.jpeg</url>
      <title>DEV Community: CreaterOS</title>
      <link>https://dev.to/createros</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/createros"/>
    <language>en</language>
    <item>
      <title>Paintinglite -- Sqlite3 SDK Specially Designed For iOS</title>
      <dc:creator>CreaterOS</dc:creator>
      <pubDate>Tue, 18 May 2021 04:11:17 +0000</pubDate>
      <link>https://dev.to/createros/paintinglite-sqlite3-sdk-specially-designed-for-ios-2k0c</link>
      <guid>https://dev.to/createros/paintinglite-sqlite3-sdk-specially-designed-for-ios-2k0c</guid>
      <description>&lt;h1&gt;
  
  
  Paintinglite
&lt;/h1&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/CreaterOS/Paintinglite.git"&gt;https://github.com/CreaterOS/Paintinglite.git&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pod installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod'Paintinglite', :git =&amp;gt;'https://github.com/CreaterOS/Paintinglite.git'#, :tag =&amp;gt; '2.1.1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Paintinglite is an excellent and fast Sqlite3 database framework. Paintinglite has good encapsulation of data, fast data insertion characteristics, and can still show good resource utilization for huge amounts of data.&lt;br&gt;
Paintinglite supports object mapping and has carried out a very lightweight object encapsulation on sqlite3. It establishes a mapping relationship between POJOs and database tables. Paintinglite can automatically generate SQL statements and manually write SQL statements to achieve convenient development and efficient querying. All-in-one lightweight framework.&lt;/p&gt;


&lt;h1&gt;
  
  
  Database operation (PaintingliteSessionManager)
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1. Build a library
&lt;/h2&gt;
&lt;h6&gt;
  
  
  Create PaintingliteSessionManager, create a database through the manager.
&lt;/h6&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)openSqlite:(NSString *)fileName;

-(Boolean)openSqlite:(NSString *)fileName completeHandler:(void(^ __nullable)(NSString *filePath,PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;*&lt;em&gt;Paintinglite has a good processing mechanism. It creates a database by passing in the database name. Even if the database suffix is ​​not standardized, it can still create a database with a .db suffix. *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM openSqlite:@"sqlite"];
[self.sessionM openSqlite:@"sqlite02.db"];
[self.sessionM openSqlite:@"sqlite03.image"];
[self.sessionM openSqlite:@"sqlite04.text"];
[self.sessionM openSqlite:@"sqlite05.."];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Get the absolute path of the created database. *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM openSqlite:@"sqlite" completeHandler:^(NSString * _Nonnull filePath, PaintingliteSessionError * _Nonnull error, Boolean success) {
       if (success) {
           NSLog(@"%@",filePath);
        }
 }];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Close the library
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)releaseSqlite;

-(Boolean)releaseSqliteCompleteHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Create a table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)execTableOptForSQL:(NSString *)sql;
-(Boolean)execTableOptForSQL:(NSString *)sql completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)createTableForName:(NSString *)tableName content:(NSString *)content;
-(Boolean)createTableForName:(NSString *)tableName content:(NSString *)content completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)createTableForObj:(id)obj createStyle:(PaintingliteDataBaseOptionsCreateStyle)createStyle;
-(Boolean)createTableForObj:(id)obj createStyle:(PaintingliteDataBaseOptionsCreateStyle)createStyle completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three ways to create a table:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQL creation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execTableOptForSQL:@"CREATE TABLE IF NOT EXISTS cart(UUID VARCHAR(20) NOT NULL PRIMARY KEY,shoppingName TEXT,shoppingID INT(11))" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success) {
        if (success) {
            NSLog(@"===CREATE TABLE SUCCESS===");
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Table name creation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM createTableForName:@"student" content:@"name TEXT,age INTEGER"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Object creation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User *user = [[User alloc] init];
[self.sessionM createTableForObj:user createStyle:PaintingliteDataBaseOptionsUUID];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Object creation can automatically generate primary keys:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primary key&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UUID&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ID&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4. Update table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)execTableOptForSQL:(NSString *)sql;
-(Boolean)execTableOptForSQL:(NSString *)sql completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(BOOL)alterTableForName:(NSString *__nonnull)oldName newName:(NSString *__nonnull)newName;
-(BOOL)alterTableForName:(NSString *__nonnull)oldName newName:(NSString *__nonnull)newName completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(BOOL)alterTableAddColumnWithTableName:(NSString *)tableName columnName:(NSString *__nonnull)columnName columnType:(NSString *__nonnull)columnType;
-(BOOL)alterTableAddColumnWithTableName:(NSString *)tableName columnName:(NSString *__nonnull)columnName columnType:(NSString *__nonnull)columnType completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(BOOL)alterTableForObj:(id)obj;
-(BOOL)alterTableForObj:(id)obj completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three ways to update the table:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;SQL Update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Table name update [table name | table field]&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM alterTableForName:@"cart" newName:@"carts"];
[self.sessionM alterTableAddColumnWithTableName:@"carts" columnName:@"newColumn" columnType:@"TEXT"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Object update
Update User table operation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;

NS_ASSUME_NONNULL_BEGIN

@interface User: NSObject

@property (nonatomic,strong)NSString *name;
@property (nonatomic,strong)NSNumber *age;
@property (nonatomic,strong)NSMutableArray&amp;lt;id&amp;gt; *mutableArray;

@end

NS_ASSUME_NONNULL_END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the mapping relationship between the table and the object, the table fields are automatically updated according to the object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User *user = [[User alloc] init];
[self.sessionM alterTableForObj:user];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Delete operation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)execTableOptForSQL:(NSString *)sql;
-(Boolean)execTableOptForSQL:(NSString *)sql completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)dropTableForTableName:(NSString *)tableName;
-(Boolean)dropTableForTableName:(NSString *)tableName completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)dropTableForObj:(id)obj;
-(Boolean)dropTableForObj:(id)obj completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three ways to delete a table:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQL operations&lt;/li&gt;
&lt;li&gt;Table name deletion
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execTableOptForSQL:@"DROP TABLE carts" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success) {
        if (success) {
            NSLog(@"===DROP TABLE SUCCESS===");
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Object deletion
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User *user = [[User alloc] init];
[self.sessionM dropTableForObj:user];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Table operation
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1. Query
&lt;/h3&gt;

&lt;p&gt;*&lt;em&gt;Query can provide the feature of query results encapsulated in array or directly encapsulated by object. *&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;General inquiry
-General enquiries
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray *)execQuerySQL:(NSString *__nonnull)sql;
-(Boolean)execQuerySQL:(NSString *__nonnull)sql completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success,NSMutableArray&amp;lt;NSDictionary *&amp;gt; *resArray))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execQuerySQL:@"SELECT * FROM student" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray) {
        if (success) {
            for (NSDictionary *dict in resArray) {
                NSLog(@"%@",dict);
            }
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:35:45.967569+0800 Paintinglite[5805:295051] {&lt;br&gt;
age = 21;&lt;br&gt;
name = CreaterOS;&lt;br&gt;
}&lt;br&gt;
2020-06-27 15:35:45.967760+0800 Paintinglite[5805:295051] {&lt;br&gt;
age = 19;&lt;br&gt;
name = Painting;&lt;br&gt;
}&lt;br&gt;
2020-06-27 15:35:45.967879+0800 Paintinglite[5805:295051] {&lt;br&gt;
age = 21;&lt;br&gt;
name = CreaterOS;&lt;br&gt;
}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-Package query&lt;/p&gt;

&lt;p&gt;Encapsulated query can encapsulate query results into objects corresponding to table fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(id)execQuerySQL:(NSString *__nonnull)sql obj:(id)obj;
-(Boolean)execQuerySQL:(NSString *__nonnull)sql obj:(id)obj completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt; *resObjList))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student *stu = [[Student alloc] init];
[self.sessionM execQuerySQL:@"SELECT * FROM student" obj:stu completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
  if (success) {
    for (Student *stu in resObjList) {
      NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
    }
  }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:39:27.306786+0800 Paintinglite[5892:302879] stu.name = CreaterOS and stu.age = 21&lt;br&gt;
2020-06-27 15:39:27.306961+0800 Paintinglite[5892:302879] stu.name = Painting and stu.age = 19&lt;br&gt;
2020-06-27 15:39:27.307110+0800 Paintinglite[5892:302879] stu.name = CreaterOS and stu.age = 21&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Conditional query&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Conditional query syntax rules:&lt;br&gt;
-Subscripts start from 0&lt;br&gt;
-Use? As a placeholder for conditional parameters&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM user WHERE name =? And age =?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray&amp;lt;NSDictionary *&amp;gt; *)execPrepareStatementSql;
-(Boolean)execPrepareStatementSqlCompleteHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execQuerySQLPrepareStatementSql:@"SELECT * FROM student WHERE name = ?"];
[self.sessionM setPrepareStatementPQLParameter:0 paramter:@"CreaterOS"];
NSLog(@"%@",[self.sessionM execPrepareStatementSql]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:44:06.664951+0800 Paintinglite&lt;a href="https://dev.to%7B&amp;lt;br&amp;gt;%0Aage%20=%2021;&amp;lt;br&amp;gt;%0Aname%20=%20CreaterOS;&amp;lt;br&amp;gt;%0A%7D,&amp;lt;br&amp;gt;%0A%7B&amp;lt;br&amp;gt;%0Aage%20=%2021;&amp;lt;br&amp;gt;%0Aname%20=%20CreaterOS;&amp;lt;br&amp;gt;%0A%7D"&gt;5984:310580&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Fuzzy query
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray&amp;lt;NSDictionary *&amp;gt; *)execLikeQuerySQLWithTableName:(NSString *__nonnull)tableName field:(NSString *__nonnull)field like:(NSString *__nonnull)like;
-(Boolean)execLikeQuerySQLWithTableName:(NSString *__nonnull)tableName field:(NSString *__nonnull)field like:(NSString *__nonnull)like completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray))completeHandler;

-(id)execLikeQuerySQLWithField:(NSString *__nonnull)field like:(NSString *__nonnull)like obj:(id)obj;
-(Boolean)execLikeQuerySQLWithField:(NSString *__nonnull)field like:(NSString *__nonnull)like obj:(id)obj completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt;* resObjList))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execLikeQuerySQLWithTableName:@"student" field:@"name" like:@"%t%" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray) {
        if (success) {
            for (NSDictionary *dict in resArray) {
                NSLog(@"%@",dict);
            }
        }
}];

Student *stu = [[Student alloc] init];
[self.sessionM execLikeQuerySQLWithField:@"name" like:@"%t%" obj:stu completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
  if (success) {
    for (NSDictionary *dict in resArray) {
      NSLog(@"%@",dict);
    }
  }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:46:31.310495+0800 Paintinglite[6030:314851] {&lt;br&gt;
age = 21;&lt;br&gt;
name = CreaterOS;&lt;br&gt;
}&lt;br&gt;
2020-06-27 15:46:31.310701+0800 Paintinglite[6030:314851] {&lt;br&gt;
age = 19;&lt;br&gt;
name = Painting;&lt;br&gt;
}&lt;br&gt;
2020-06-27 15:46:31.310868+0800 Paintinglite[6030:314851] {&lt;br&gt;
age = 21;&lt;br&gt;
name = CreaterOS;&lt;br&gt;
}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Paging query
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray&amp;lt;NSDictionary *&amp;gt; *)execLimitQuerySQLWithTableName:(NSString *__nonnull)tableName limitStart:(NSUInteger)start limitEnd:(NSUInteger)end;
-(Boolean)execLimitQuerySQLWithTableName:(NSString *__nonnull)tableName limitStart:(NSUInteger)start limitEnd:(NSUInteger)end completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray))completeHandler;

-(id)execLimitQuerySQLWithLimitStart:(NSUInteger)start limitEnd:(NSUInteger)end obj:(id)obj;
-(Boolean)execLimitQuerySQLWithLimitStart:(NSUInteger)start limitEnd:(NSUInteger)end obj:(id)obj completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt;* resObjList))completeHandler ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execLimitQuerySQLWithTableName:@"student" limitStart:0 limitEnd:1 completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray) {
        if (success) {
            for (NSDictionary *dict in resArray) {
                NSLog(@"%@",dict);
            }
        }
}];

Student *stu = [[Student alloc] init];
[self.sessionM execLimitQuerySQLWithLimitStart:0 limitEnd:1 obj:stu completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
  if (success) {
    for (Student *stu in resObjList) {
      NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
    }
  }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:51:13.026776+0800 Paintinglite[6117:323796] stu.name = CreaterOS and stu.age = 21&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Sort query
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray&amp;lt;NSDictionary *&amp;gt; *)execOrderByQuerySQLWithTableName:(NSString *__nonnull)tableName orderbyContext:(NSString *__nonnull)orderbyContext orderStyle:(PaintingliteOrderByStyle)orderStyle;
-(Boolean)execOrderByQuerySQLWithTableName:(NSString *__nonnull)tableName orderbyContext:(NSString *__nonnull)orderbyContext orderStyle:(PaintingliteOrderByStyle)orderStyle completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray))completeHandler;

-(id)execOrderByQuerySQLWithOrderbyContext:(NSString *__nonnull)orderbyContext orderStyle:(PaintingliteOrderByStyle)orderStyle obj:(id)obj;
-(Boolean)execOrderByQuerySQLWithOrderbyContext:(NSString *__nonnull)orderbyContext orderStyle:(PaintingliteOrderByStyle)orderStyle obj:(id)obj completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt;* resObjList) )completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student *student = [[Student alloc] init];
[self.sessionM execOrderByQuerySQLWithOrderbyContext:@"name" orderStyle:PaintingliteOrderByDESC obj:student completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray&amp;lt;NSDictionary *&amp;gt; * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resOb
  if (success) {
    for (Student *stu in resObjList) {
      NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
    }
  }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 15:55:06.714604+0800 Paintinglite[6196:331097] stu.name = Painting and stu.age = 19&lt;br&gt;
2020-06-27 15:55:06.714801+0800 Paintinglite[6196:331097] stu.name = CreaterOS and stu.age = 21&lt;br&gt;
2020-06-27 15:55:06.714962+0800 Paintinglite[6196:331097] stu.name = CreaterOS and stu.age = 21&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Increase data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)insert:(NSString *__nonnull)sql;
-(Boolean)insert:(NSString *__nonnull)sql completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)insertWithObj:(id)obj completeHandler:(void(^ __nullable)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;SQL Insert
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM insert:@"INSERT INTO student(name,age) VALUES('CreaterOS',21),('Painting',19)"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Object Insertion
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;

NS_ASSUME_NONNULL_BEGIN

@interface Student: NSObject
@property (nonatomic,strong)NSString *name;
@property (nonatomic,strong)NSNumber *age;
@end

NS_ASSUME_NONNULL_END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student *stu = [[Student alloc] init];
stu.name = @"ReynBryant";
stu.age = [NSNumber numberWithInteger:21];
[self.sessionM insertWithObj:stu completeHandler:nil];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For the huge amount of data, Paintinglit can still show good efficiency. It only takes 6ms-7ms to read 16 million pieces of data at a time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Update data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)update:(NSString *__nonnull)sql;
-(Boolean)update:(NSString *__nonnull)sql completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
-(Boolean)updateWithObj:(id)obj condition:(NSString *__nonnull)condition completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;SQL update data
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM update:@"UPDATE student SET name ='Painting' WHERE name ='ReynBryant'"];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Object update
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Student *stu = [[Student alloc] init];
   stu.name = @"CreaterOS";
   [self.sessionM updateWithObj:stu condition:@"age = 21" completeHandler:nil];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Added update operation, which can be updated by object transfer method&lt;br&gt;
For example:&lt;br&gt;
User *user = [[User alloc] init];&lt;br&gt;
user.name = @"CreaterOS";&lt;br&gt;
user.age = 21;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Delete data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)del:(NSString *__nonnull)sql;
-(Boolean)del:(NSString *__nonnull)sql completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  PQL Syntax (PaintingliteSessionManager)
&lt;/h1&gt;

&lt;p&gt;Through the PQL statement, Paintinglite can automatically help you complete the writing of the SQL statement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PQL grammar rules (uppercase | the class name must be associated with the table)&lt;br&gt;
FROM + class name + [condition]&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(id)execPrepareStatementPQL;
-(Boolean)execPrepareStatementPQLWithCompleteHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt;* resObjList))completeHandler;

-(void)execQueryPQLPrepareStatementPQL:(NSString *__nonnull)prepareStatementPQL;
-(void)setPrepareStatementPQLParameter:(NSUInteger)index paramter:(NSString *__nonnull)paramter;
-(void)setPrepareStatementPQLParameter:(NSArray *__nonnull)paramter;

-(id)execPQL:(NSString *__nonnull)pql;
-(Boolean)execPQL:(NSString *__nonnull)pql completeHandler:(void(^)(PaintingliteSessionError *error,Boolean success,NSMutableArray *resArray,NSMutableArray&amp;lt;id&amp;gt;* resObjList))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execPQL:@"FROM Student WHERE name ='CreaterOS'" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
        if (success) {
            for (Student *stu in resObjList) {
                NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
            }
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 16:16:47.145774+0800 Paintinglite[6753:369828] stu.name = CreaterOS and stu.age = 21&lt;br&gt;
2020-06-27 16:16:47.145928+0800 Paintinglite[6753:369828] stu.name = CreaterOS and stu.age = 21&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execPQL:@"FROM Student LIMIT 0,1" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
        if (success) {
            for (Student *stu in resObjList) {
                NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
            }
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execPQL:@"FROM Student WHERE name LIKE'%t%'" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
        if (success) {
            for (Student *stu in resObjList) {
                NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
            }
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execPQL:@"FROM Student ORDER BY name ASC" completeHandler:^(PaintingliteSessionError * _Nonnull error, Boolean success, NSMutableArray * _Nonnull resArray, NSMutableArray&amp;lt;id&amp;gt; * _Nonnull resObjList) {
        if (success) {
            for (Student *stu in resObjList) {
                NSLog(@"stu.name = %@ and stu.age = %@",stu.name,stu.age);
            }
        }
}];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.sessionM execQueryPQLPrepareStatementPQL:@"FROM Student WHERE name = ?"];
[self.sessionM setPrepareStatementPQLParameter:@[@"CreaterOS"]];
NSLog(@"%@",[self.sessionM execPrepareStatementPQL]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;2020-06-27 16:26:11.404815+0800 Paintinglite&lt;a href=""&gt;7025:389268&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Aggregate function (PaintingliteAggregateFunc)
&lt;/h1&gt;

&lt;p&gt;Paintinglite encapsulates Sqlite3 aggregation functions, and automatically writes SQL statements to get the aggregation results.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Count
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.aggreageteF count:[self.sessionM getSqlite3] tableName:@"eletest" completeHandler:^(PaintingliteSessionError * _Nonnull sessionerror, Boolean success, NSUInteger count) {
        if (success) {
            NSLog(@"%zd",count);
        }
 }];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Max
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.aggreageteF max:[self.sessionM getSqlite3] field:@"age" tableName:@"eletest" completeHandler:^(PaintingliteSessionError * _Nonnull sessionerror, Boolean success, double max) {
        if (success) {
            NSLog(@"%.2f",max);
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Min
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.aggreageteF min:[self.sessionM getSqlite3] field:@"age" tableName:@"eletest" completeHandler:^(PaintingliteSessionError * _Nonnull sessionerror, Boolean success, double min) {
        if (success) {
            NSLog(@"%.2f",min);
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Sum
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.aggreageteF sum:[self.sessionM getSqlite3] field:@"age" tableName:@"eletest" completeHandler:^(PaintingliteSessionError * _Nonnull sessionerror, Boolean success, double sum) {
        if (success) {
            NSLog(@"%.2f",sum);
        }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Avg
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.aggreageteF avg:[self.sessionM getSqlite3] field:@"age" tableName:@"eletest" completeHandler:^(PaintingliteSessionError * _Nonnull sessionerror, Boolean success, double avg) {
        if (success) {
            NSLog(@"%.2f",avg);
        }
}];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Transaction (PaintingliteTransaction)
&lt;/h1&gt;

&lt;p&gt;Sqlite3 development defaults that an insert statement is a transaction. If there are multiple insert statements, the transaction will be repeated. This consumes a lot of resources. Paintinglite provides an operation to start a transaction (display transaction).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+ (void)begainPaintingliteTransaction:(sqlite3 *)ppDb;
+ (void)commit:(sqlite3 *)ppDb;
+ (void)rollback:(sqlite3 *)ppDb;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Daily development integration&lt;/p&gt;

&lt;p&gt;@try {&lt;br&gt;
} @catch (NSException *exception) {&lt;br&gt;
} @finally {&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Use&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Cascade operation (PaintingliteCascadeShowerIUD)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)cascadeInsert:(sqlite3 *)ppDb obj:(id)obj completeHandler:(void (^ __nullable)(PaintingliteSessionError *sessionError,Boolean success,NSMutableArray *resArray))completeHandler;

-(Boolean)cascadeUpdate:(sqlite3 *)ppDb obj:(id)obj condatation:(NSArray&amp;lt;NSString *&amp;gt; * __nonnull)condatation completeHandler:(void (^__nullable)(PaintingliteSessionError *sessionError,Boolean success,NSMutableArray *resArray)) completeHandler;

-(Boolean)cascadeDelete:(sqlite3 *)ppDb obj:(id)obj condatation:(NSArray&amp;lt;NSString *&amp;gt; * __nonnull)condatation completeHandler:(void (^__nullable)(PaintingliteSessionError *sessionError,Boolean success,NSMutableArray *resArray)) completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cascade is divided into three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Insert
&amp;gt; For cascading insert operations, we need to connect two related tables through a variable array, for example:
&amp;gt; The user table and the student table are linked,
&amp;gt; A user can contain multiple students&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, you can set variable data in the user to save multiple students, and then hand the user object to Paintinglite to write data in multiple tables at once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User *user = [[User alloc] init];
user.name = @"Jay";
user.age = [NSNumber numberWithInteger:40];
user.studentsArray = [NSMutableArray array];

Student *student = [[Student alloc] init];
student.name = @"Hony";
student.age = [NSNumber numberWithInteger:30];

Student *student1 = [[Student alloc] init];
student1.name = @"Jack";
student1.age = [NSNumber numberWithInteger:41];

[user.studentsArray addObject:student];
[user.studentsArray addObject:student1];

[self.cascade cascadeInsert:[self.sessionM getSqlite3] obj:user completeHandler:^(PaintingliteSessionError * _Nonnull sessionError, Boolean success, NSMutableArray * _Nonnull resArray) {
    if (success) {
        NSLog(@"%@",resArray);
    }
}];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update
The function is the same as cascading insertion. Pass in the user object, including the collection of student tables, and pass in the modification conditions as an array. Paintinglite can automatically update multiple tables. (Different conditions of multiple tables corresponding to the condition array)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;name ='CreaterOS' corresponds to the user table&lt;/p&gt;

&lt;p&gt;name ='OS...' corresponds to the student table&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.cascade cascadeUpdate:[self.sessionM getSqlite3] obj:user condatation:@[@"WHERE name ='CreaterOS'",@"WHERE name ='OS...'"] completeHandler:^(PaintingliteSessionError * _Nonnull sessionError , Boolean success, NSMutableArray * _Nonnull resArray) {
     if (success) {
            NSLog(@"%@",resArray);
     }
 }];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Delete
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.cascade cascadeDelete:[self.sessionM getSqlite3] obj:user condatation:@[@"name ='WHY'",@"name ='YHD...'"] completeHandler:^(PaintingliteSessionError * _Nonnull sessionError, Boolean success, NSMutableArray * _Nonnull resArray) {
       if (success) {
           NSLog(@"%@",resArray);
       }
}];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Log Mode (PaintingliteLog)
&lt;/h1&gt;

&lt;p&gt;Paintinglite provides developers with a logging function, which can record key operations on sqlite3 data during development, and is marked with a timestamp. Developers can easily read the log through the database name, or according to the required time node or the status of success and failure Selectively read the log. It facilitates the debugging after the software is online.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(void)readLogFile:(NSString *__nonnull)fileName;

-(void)readLogFile:(NSString *)fileName dateTime:(NSDate *__nonnull)dateTime;

-(void)readLogFile:(NSString *)fileName logStatus:(PaintingliteLogStatus)logStatus;

-(void)removeLogFile:(NSString *)fileName;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Log module update
&lt;/h2&gt;

&lt;p&gt;To write log files in batches through the first-level cache, it is recommended that the developer instantiate the PaintingliteCache in AppDelegate, and manually call the log write method in applicationDidEnterBackground:(UIApplication *)application and applicationWillTerminate:(UIApplication *)application, then the cache can not be reached The log of the base point is written to the log file in time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[self.cache pushCacheToLogFile];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Database backup (PaintingliteBackUpManager)
&lt;/h1&gt;

&lt;p&gt;Database migration is a problem that developers often care about. It has always been a headache for sqlite3 to port the client SQL Server MySQL and Orcale. Paintinglite is very friendly to provide developers with four database backup files, including from building a database to inserting data. Paintinglite writes backup files for developers. Developers only need to upload these sql files and run them to get and move the device. Exactly the same data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PaintingliteBackUpSqlite3,
PaintingliteBackUpMySql,
PaintingliteBackUpSqlServer,
PaintingliteBackUpORCALE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)backupDataBaseWithName:(sqlite3 *)ppDb sqliteName:(NSString *)sqliteName type:(PaintingliteBackUpManagerDBType)type completeHandler:(void(^ __nullable)(NSString *saveFilePath))completeHandler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="/Users/bryantreyn/Library/Application%20Support/typora-user-images/image-20200627211330562.png" class="article-body-image-wrapper"&gt;&lt;img src="/Users/bryantreyn/Library/Application%20Support/typora-user-images/image-20200627211330562.png" alt="image-20200627211330562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Split table (PaintingliteSplitTable)
&lt;/h1&gt;

&lt;p&gt;The time-consuming operation of table query with too large amount of data is huge. The Paintinglite test phase provides the operation of splitting the table, splitting the large table into multiple small tables, and the amount of splitting is determined by the developer.&lt;br&gt;
Paintinglite provides split table operation for the first time, and the module is still being tested. Later version iterations will focus on optimizing this part of resource consumption and CPU usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
  * tableName: database name
  * basePoint: the number of splits
  */
-(Boolean)splitTable:(sqlite3 *)ppDb tabelName:(NSString *__nonnull)tableName basePoint:(NSUInteger)basePoint;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Query operation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(NSMutableArray *)selectWithSpliteFile:(sqlite3 *)ppDb tableName:(NSString *__nonnull)tableName basePoint:(NSUInteger)basePoint;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Insert operation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)insertWithSpliteFile:(sqlite3 *)ppDb tableName:(NSString *)tableName basePoint:(NSUInteger)basePoint insertSQL:(NSString *)insertSQL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update operation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)updateWithSpliteFile:(sqlite3 *)ppDb tableName:(NSString *)tableName basePoint:(NSUInteger)basePoint updateSQL:(NSString *)updateSQL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Delete operation
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)deleteWithSpliteFile:(sqlite3 *)ppDb tableName:(NSString *)tableName basePoint:(NSUInteger)basePoint deleteSQL:(NSString *)deleteSQL;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Stress test (PaintinglitePressureOS)
&lt;/h1&gt;

&lt;p&gt;The PaintinglitePressureOS system is a stress testing system. It evaluates the reasonableness of database read and write consumption time, resource consumption and memory usage, and supports the generation of stress test reports. (No report is generated by default)&lt;/p&gt;

&lt;p&gt;Paintinglite can perform different measurement and calculation of memory consumption status according to different devices, allowing developers to more clearly design a more reasonable database table structure on different iPhones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(Boolean)paintingliteSqlitePressure;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;#### XML file configuration rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The XML mapping file strictly abides by the DTD rules, which provides ,,,,&amp;lt;/ select&amp;gt;, , ,  and other basic tags;&lt;/li&gt;
&lt;li&gt;The XML mapping file needs to be configured corresponding to the class created by the table (POJO mapping);&lt;/li&gt;
&lt;li&gt;The XML mapping file format has strict requirements (the v2.0 version has strict requirements);&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  XML mapping file hierarchy
&lt;/h4&gt;

&lt;p&gt;(1) When configuring the XML mapping file, the outermost tag is , and the mapper tag provides the namespace namespace;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;mapper namespace="..."&amp;gt;
&amp;lt;/mapper&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;namespace: Indicates the name of the table targeted by the current SQL statement operation object (the namespace content is not mandatory here, and it is recommended to be the same as the operation table name)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(2)  can configure database SQL operations inside;&lt;/p&gt;

&lt;h4&gt;
  
  
  select: Query label
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest"&amp;gt;
    SELECT * FROM eletest WHERE name =?
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;id: select the bound ID&lt;br&gt;
resultType: result return type, currently supports NSDictionary&amp;amp;&amp;amp;NSMutableDictionary | NSArray &amp;amp;&amp;amp; NSMutableArray&lt;br&gt;
parameterType: Incoming type (variable parameters do not need to be configured, parameterType must be configured for all obj methods)&lt;br&gt;
The query SQL statement can be written inside the select tag&lt;br&gt;
?: Need to replace part of the adoption?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  select: omit query
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;select id="getEleById" resultType="Eletest"&amp;gt;
?
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;When you need to use select * from tableName to query, you can omit the SQL statement and replace the SQL statement that needs to be written with a?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  insert: insert tag
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;

NS_ASSUME_NONNULL_BEGIN

@interface Eletest: NSObject
@property (nonatomic,strong)NSNumber *age;
@property (nonatomic,copy)NSString *desc;
@property (nonatomic,copy)NSString *name;
@property (nonatomic,strong)NSNumber *tage;
@property (nonatomic,copy)NSString *teacher;
@end

NS_ASSUME_NONNULL_END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;insert id="getInsertEletest" parameterType="Eletest"&amp;gt;
INSERT INTO eletest(name,age,desc,tage,teacher) VALUES (#name,#age,#desc,#tage,#teacher);
&amp;lt;/insert&amp;gt;

&amp;lt;insert id="getInsertEletestAuto" parameterType="Eletest"&amp;gt;
?
&amp;lt;/insert&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;id: insert tag binding ID&lt;br&gt;
parameterType: Incoming parameter, which must be configured here, is the class name of the POJO object (note the case)&lt;/p&gt;
&lt;h1&gt;
  
  
  name,#age,#desc,#tage,#teacher: replace the inserted value with a combination of "#+class attribute name"
&lt;/h1&gt;

&lt;p&gt;insert supports the omission of insert statements, and only needs to set the corresponding attribute values ​​for the objects that need to be passed in&lt;br&gt;
useGeneratedKeys="true" keyProperty="ID": Return the inserted primary key value&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;insert id="getInsertUserReturnPrimaryKey" parameterType="Eletest" useGeneratedKeys="true" keyProperty="ID"&amp;gt;
&amp;lt;selectKey keyProperty="ID" order="AFTER"&amp;gt;
SELECT LAST_INSERT_ID();
&amp;lt;/selectKey&amp;gt;
?
&amp;lt;/insert&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; can also be configured to insert the return value&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;keyProperty="ID": Primary key value (corresponding property value)&lt;br&gt;
order="AFTER": Call timing, AFTER&amp;amp;&amp;amp;BEFORE can be configured&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  update tag
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;update id="getUpdateEle" parameterType="Eletest"&amp;gt;
UPDATE eletest SET name = #name and tage = #tage WHERE teacher = #teacher and age = #age;
&amp;lt;/update&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;id: update tag binding ID&lt;br&gt;
parameterType: Incoming parameter, which must be configured here, is the class name of the POJO object (note the case)&lt;/p&gt;
&lt;h1&gt;
  
  
  name,#age,#tage,#teacher: replace the inserted value with a combination of "#+class attribute name"
&lt;/h1&gt;

&lt;p&gt;update supports omitting the insert statement, just set the corresponding attribute value for the object that needs to be passed in&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  delete tag
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;delete id="getDeleteUser" parameterType="Eletest"&amp;gt;
DELETE FROM eletest WHERE name = #name and teacher = #teacher and tage = #tage;
&amp;lt;/delete&amp;gt;

&amp;lt;delete id="getDeleteEleAuto" parameterType="Eletest"&amp;gt;
?
&amp;lt;/delete&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;id: delete tag binding ID&lt;br&gt;
parameterType: Incoming parameter, which must be configured here, is the class name of the POJO object (note the case)&lt;/p&gt;
&lt;h1&gt;
  
  
  name,#teacher,#tage: replace the inserted value with a combination of "#+class attribute name"
&lt;/h1&gt;

&lt;p&gt;delete supports omitting the insert statement, just set the corresponding attribute value for the object that needs to be passed in&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Advanced use of XML mapping file
&lt;/h4&gt;

&lt;h5&gt;
  
  
  &amp;amp;&amp;amp;Use
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;sql id="eletestSql"&amp;gt;id,name,age,teacher,tage,desc&amp;lt;/sql&amp;gt;
 &amp;lt;select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult"&amp;gt;
 SELECT &amp;lt;include refid="eletestSql"&amp;gt;&amp;lt;/include&amp;gt; FROM eletest
 &amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally operating SQL statements will write select id, name, age, teacher, tag, desc From eletest fields for query, and multiple field names will be used in an XML mapping file. You can use  to change the field name Package, in combination with  application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Use the  tag to configure the refid to pass in the value must be the same as the  configuration id&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Dynamic SQL operation tags
&lt;/h4&gt;

&lt;h5&gt;
  
  
   tag
&lt;/h5&gt;

&lt;p&gt;The if tag provides a dynamic judgment of whether the value of the incoming field is empty, and the statement is added if the condition is true, otherwise no statement is added.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;select id="getEleByObj" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult"&amp;gt;
SELECT &amp;lt;include refid="eletestSql"&amp;gt;&amp;lt;/include&amp;gt; FROM eletest WHERE 1 = 1 AND tage =? &amp;lt;if test="name != null and name !=''"&amp;gt;AND name = ?&amp;lt;/if&amp;gt; &amp;lt;if test="desc != null and desc !=''"&amp;gt;AND desc = ?&amp;lt;/if&amp;gt; &amp;lt;if test="teacher != null and teacher !=''"&amp;gt;AND teacher = ?&amp;lt;/if&amp;gt;
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;if test="desc != null and desc !=''"&amp;gt;&amp;lt;/if&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;test: Judgment condition, currently only supports! = operation&lt;/p&gt;

&lt;p&gt;Configure the  tag to put all the fields that need to be judged at the end of the unified judgment writing. In order to ensure the correctness of the SQL statement, add 1 = 1 after the WHERE&lt;br&gt;
Every  structure needs to be added with a larger AND&lt;br&gt;
AND desc = ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
   tag
&lt;/h5&gt;

&lt;p&gt;The where tag eliminates the restriction that the if tag must add 1 = 1 after the WHERE. At the same time, omit AND in each if structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;select id="getEleByObjWhere" resultType="NSDictionary" parameterType="Eletest" resultMap="eletestResult"&amp;gt;
SELECT &amp;lt;include refid="eletestSql"&amp;gt;&amp;lt;/include&amp;gt; FROM eletest &amp;lt;where&amp;gt;&amp;lt;if test="name != null and name !=''"&amp;gt;name = ?&amp;lt;/if&amp;gt; &amp;lt;if test="desc != null and desc !=''"&amp;gt;desc = ?&amp;lt;/if&amp;gt; &amp;lt;if test="teacher != null and teacher !=''"&amp;gt;teacher = ?&amp;lt;/if&amp;gt;&amp;lt;/where&amp;gt;
&amp;lt;/select&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  PaintingliteXMLSessionManager common methods
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; /**
 * Create SessionManager
 * xmlFileName: Each class corresponds to an XML file, and the name of the XML file is passed in
 */
 + (instancetype)buildSesssionManger:(NSString *__nonnull)xmlFileName;

 /**
 * Query one
 * methodID: Select ID of XML binding
 * condition: query condition
 */
 -(NSDictionary *)selectOne:(NSString *__nonnull)methodID condition:(id)condition,... NS_REQUIRES_NIL_TERMINATION;

 /* Query multiple */
 -(NSArray&amp;lt;id&amp;gt; *)select:(NSString *__nonnull)methodID condition:(id)condition,... NS_REQUIRES_NIL_TERMINATION;

 -(NSArray&amp;lt;id&amp;gt; *)select:(NSString *)methodID obj:(id)obj;

 /**
 * Insert
 * methodID: INSERT ID bound to XML
 * obj: the inserted object
 */
 -(Boolean)insert:(NSString *)methodID obj:(id)obj;

 /**
 * Insert return primary key ID
 * methodID: INSERT ID bound to XML
 * obj: the inserted object
 */
 -(sqlite3_int64)insertReturnPrimaryKeyID:(NSString *)methodID obj:(id)obj;

 /**
 * Update
 * methodID: INSERT ID bound to XML
 * obj: the inserted object
 */
 -(Boolean)update:(NSString *)methodID obj:(id)obj;

 /**
 * Delete
 * methodID: INSERT ID bound to XML
 * obj: the inserted object
 */
 -(Boolean)del:(NSString *)methodID obj:(id)obj;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Instance call
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; PaintingliteXMLSessionManager *xmlSessionM = [PaintingliteXMLSessionManager buildSesssionManger:[[NSBundle mainBundle] pathForResource:@"user" ofType:@"xml"]];
 [xmlSessionM openSqlite:@"sqlite"];

//Inquire
NSLog(@"%@",[xmlSessionM selectOne:@"eletest.getEleById" condition:[NSNumber numberWithInt:1],[NSNumber numberWithInt:21],nil]);
 NSLog(@"%@",[xmlSessionM select:@"eletest.getEleById" condition:[NSNumber numberWithInt:1],[NSNumber numberWithInt:21], nil]);

 Eletest *eletest = [[Eletest alloc] init];
 eletest.name = @"CreaterOS";
 eletest.age = [NSNumber numberWithInteger:21];
 eletest.desc = @"CreaterOS";
 eletest.teacher = @"CreaterOS";
 eletest.tage = [NSNumber numberWithInteger:21];

 NSLog(@"%zd",[[xmlSessionM select:@"eletest.getEleByObj" obj:eletest] count]);
 NSLog(@"%zd",[[xmlSessionM select:@"eletest.getEleByObjWhere" obj:eletest] count]);

 //insert
 [xmlSessionM insert:@"eletest.getInsertEletest" obj:eletest];

 NSLog(@"%lu",(unsigned long)[xmlSessionM insertReturnPrimaryKeyID:@"eletest.getInsertUserReturnPrimaryKey" obj:eletest]);

 //delete
 [xmlSessionM del:@"eletest.getDeleteUser" obj:eletest];
 [xmlSessionM del:@"eletest.getDeleteEleAuto" obj:eletest];

 //Update
 [xmlSessionM update:@"eletest.getUpdateEle" obj:eletest];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Constraint
&lt;/h1&gt;

&lt;p&gt;In order to achieve better operation and comply with database specifications, table names are all lowercase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contribute to this project
&lt;/h3&gt;

&lt;p&gt;If you have a feature request or bug report, please feel free to send &lt;a href="//mailto:863713745@qq.com"&gt;863713745@qq.com&lt;/a&gt; to upload the problem, and we will provide you with revisions and help as soon as possible. Thank you very much for your support.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Disclosure
&lt;/h3&gt;

&lt;p&gt;If you have found the Paintinglite security vulnerabilities and vulnerabilities that need to be modified, you should email them to &lt;a href="//mailto:863713745@qq.com"&gt;863713745@qq.com&lt;/a&gt; as soon as possible. thank you for your support.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>github</category>
      <category>sql</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
