All Products
Search
Document Center

DAO storage

Last Updated: May 25, 2021

General KV storage can only store simple data or encapsulated OC objects, and does not support data search. When the business requires the access to SQLite, the DAO function of Datacenter can be utilized for simplification and encapsulation. It works as follows:

DAO

  1. Define an xml configuration file to describe the functions, returned data types and encrypted fields of various SQLite operations.
  2. Define an interface for DAO objects, DAOInterface (@protocol). The interface method names and arguments should stay consistent with those described in the configuration file.
  3. The business layer passes the xml configuration file to the daoWithPath method of APDataCenter, and the DAO access object is generated. The object is directly converted into id<DAOInterface>.
  4. Next, the business layer will be able to directly call the DAO object methods, and Datacenter will translate the method into the database operations described in the configuration file.

Examples

  • The first line of the configuration file defines the default table name and database version, as well as the initialization method.
  • insertItem and getItem are two methods for inserting and reading data. They receive arguments and format the arguments into SQL expressions.
  • createTable will be called once on the underlying layer by default.

       
    1. <module name="Demo" initializer="createTable" tableName="demoTable" version="1.0">
    2. <update id="createTable">
    3. create table if not exists ${T} (index integer primary key, content text)
    4. </update>
    5. <insert id="insertItem" arguments="content">
    6. insert into ${T} (content) values(#{content})
    7. </insert>
    8. <select id="getItem" arguments="index" result="string">
    9. select * from ${T} where index = #{index}
    10. </select>
    11. </module>
  • Define the DAO API:

       
    1. @protocol DemoProtocol <APDAOProtocol>
    2. - (APDAOResult*)insertItem:(NSString*)content;
    3. - (NSString*)getItem:(NSNumber*)index;
    4. @end
  • Create a DAO proxy object. Suppose the configuration file is named demo_config.xml and is located in Main Bundle.

  • Write a piece of data with the insertItem method, acquire its index, and then read the written data with the index.

       
    1. NSString* filePath = [[NSBundle mainBundle] pathForResource:@"demo_config" ofType:@"xml"];
    2. id<DemoProtocol> proxy = [[APDataCenter defaultDataCenter] daoWithPath:filePath userDependent:YES];
    3. [proxy insertItem:@"something"];
    4. long long lastIndex = [proxy lastInsertRowId];
    5. NSString* content = [proxy getItem:[NSNumber numberWithInteger:lastIndex]];
    6. NSLog(@"content %@", content);
  • lastInsertRowId is a method of APDAOProtocol, used for getting the rowId of the row last inserted. To enable the DAO object to support this method, you only need to make the DemoProtocol inherit from the APDAOProtocol in declaration.

Keyword

module

 
  1. <module name="demo" initializer="createTable" tableName="tableDemo" version="1.5" resetOnUpgrade="true" upgradeMinVersion="1.2">
  • initializer: Optional. DAO considers the update method specified by initializer as a method for building a database table, which will be executed once by default when the first DAO request is initiated.
  • tableName: Specifies the table name for the default operation in the method below. It can be replaced by ${T} or ${t} n SQL statements, so that you don’t have to input the table name every time. It is recommended that one configuration file be targeted to one table. tableName can be empty, so that the same configuration file can operate on multiple tables sharing the same format. For example, to process chat messages in tables, the setTableName method of DAO objects can be called for setting the name of the table to be operated on.
  • version: Represents the version number of the configuration file, in x.x format. After the table is created, tableName will serve as the key and the table version will be saved to the TableVersions table in the database file. TableVersions will work in concert with the upgrade block for table updates.
  • resetOnUpgrade: If its value is true or YES, when version is updated, the old table will be deleted instead of calling the upgrade block. If this argument does not exist, its value is false by default.
  • upgradeMinVersion: If it is not empty, database files of a earlier earlier than its value will be reset directly. Otherwise the upgrade operation will be performed.

const

 
  1. <const table_columns="(id, time, content, uin, read)"/>

Define a constant of the string type. table_columns is the name of a constant, and the content after the equal sign (=) is the constant value. The constant can be referenced in the configuration file as ${constant name} .

select

 
  1. <select id="find" arguments="id, time" result=":messageModelMap">
  2. select * from ${T} where id = #{id} and time > @{time}
  3. </select>

@arguments:

  • List of the argument names, separated by “,”. Incoming arguments from the caller are named in turn according to the descriptions in arguments. Selectors of DAO objects will not carry the argument name in calling, so arguments must be named in sequence here.
  • If an argument has a dollar sign ($) at its beginning, this argument does not accept the nil value. Calls of DAO interfaces from the business layer allow nil arguments. But if an argument has a dollar sign ($) at its beginning and the caller accidentally passes a nil value, the DAO call will fail automatically to prevent unexpected issues from happening.
  • For more information about how to reference parameters, see Reference methods.

For example, in the code above, the corresponding selector is as follows:

 
  1. - (MessageModel*)find:(NSNumber*)id time:(NSNumber*)time;

If the DAO object calls [daoProxy find:@1234 time:@2014], the ready SQL statement will be:

 
  1. select * from tableDemo where id = ? and time > 2014

The NSNumber value @1234 will be handed over to SQLite for binding.

@result:

  • result can be the returned value of the DAO method. The use of square brackets [] indicates to return the array type of values and iterations occur for the returned values of the SELECT method until no result is returned from SQLite. If the square brackets [] are removed, it indicates to return one result only and one iteration is conducted for the SELECT method. It is similar to the next method for FMResultSet in FMDB database.

Returned types:

  • int: only returns one result of the [NSNumber numberWithInt] type. Note the possibility of overflow.
  • long long: only returns one result of the [NSNumber numberWithLongLong] type.
  • bool: only returns one result of the [NSNumber numberWithBool] type.
  • double: only returns one result of the [NSNumber numberWithDouble] type.
  • string: only returns one result of the NSString* type.
  • binary: only returns one result of the NSData* type.
  • [int]: an array, with values of the [NSNumber numberWithInt] type in the array.
  • [long long]: an array, with values of the [NSNumber numberWithLongLong] type in the array.
  • [bool]: an array, with values of the [NSNumber numberWithBool] type in the array.
  • [double]: an array, with values of the [NSNumber numberWithDouble] type in the array.
  • [string]: an array, with values of the NSString* type in the array.
  • [binary]: an array, with values of the NSData* type in the array.
  • [{}]: an array, with mapping of column name->column value in the array.
  • [AType]: an array, with filled custom classes in the array.
  • {}: only one result, mapping of column name->column value.
  • AType: only one result, with the filled custom class.
  • [:AMap]: an array, with XML-defined mapped objects of AMap in the array.
  • :AMap: only one result. The AMap defined in the configuration file is used to describe the object.

In the example above, the returned type is :messageModelMap. The Objective-C types returned and columns that require special mapping will be defined in messageModelMap. Refer to the keyword map.

@foreach:

The SELECT method also supports the foreach field and its usage is similar to that of the insert, update, and delete methods to be introduced later. The difference is, if the select method specifies the foreach argument, the SELECT operation will be executed for N times, and the results will be returned in an array. So if the select method in DAO specifies the foreach argument, its return value must be defined as NSArray* in the protocol.

insert, update, delete

 
  1. <insert id="addMessages" arguments="messages" foreach="messages.model">
  2. insert or replace into ${T} (id, content, uin, read) values(#{model.msgId}, #{model.content}, #{model.uin}, #{model.read})
  3. </insert>
  4. <update id="createTable">
  5. <step>
  6. create table if not exists ${T} (id integer primary key, content text, uin integer, read boolean)
  7. </step>
  8. <step>
  9. create index if not exists uin_idx on ${T} (uin)
  10. </step>
  11. </update>
  12. <delete id="remove" arguments="msgId">
  13. delete from ${T} where msgId = #{msgId}
  14. </delete>
  • The INSERT, UPDATE and DELETE methods share the same format. These methods’ argument concatenation and reference are the same with that of the SELECT method.
  • The INSERT and DELETE keywords serve to differentiate purposes of methods. You can write a “DELETE FROM TABLE” operation in the “UPDATE” function.
  • In DAO interfaces, when the INSERT, UPDATE or DELETE methods are executed, the returned value is APDAOResult*, indicating whether the execution succeeded.

@foreach:

  • When a ‘foreach’ field follows the INSERT, UPDATE or DELETE methods, the method will query every element in the argument array one by one when the method is called.
  • The ‘foreach’ field must follow the format collectionName.item. The “collectionName” must correspond to an argument in “arguments” and specify the loop container object. It must be of the NSArray or NSSet type when called. The “item” represents the object fetched from the container and will be used as the loop variable. The item name cannot be duplicated with that of any argument in the “arguments”. The item can be used as a normal argument in the SQL statement.

For example, the delegate method is:

 
  1. - (void)addMessages:(NSArray*)messages;

The messages is a MessageModel array. For every model in the messages, an SQL call will be executed so that elements in the array will be inserted to the database in one shot while the upper layer does not need to care about the loop call. The underlying layer will merge the operation into one transaction to improve efficiency.

step

 
  1. <upgrade toVersion='3.2'>
  2. <step resumable="true">alter table ${T} add column1 text</step>
  3. <step resumable="true">alter table ${T} add column2 text</step>
  4. </upgrade>
  • In INSERT, UPDATE, DELETE, and UPGRADE methods, you may run into such a circumstance: To execute a DAO method, the SQL update operation is called for multiple times to execute multiple SQL statements. For example, after a table is created, the user wants to create some indexes. The statement packaged in the function will be executed independently as one SQL update operation, and the underlying layer will merge all the operations into one transaction, such as the createTable method in the figure above.
  • If the step clause exists in a function, no texts are allowed outside the step. The step cannot contain another step.

@resumable:

  • When the SQL execution generated by this step statement fails, do you continue to execute the following statement. If this argument does not exist, its value is false by default. That is, step is executed in sequence. When a failure occurs, the whole DAO method thinks it fails.

map

 
  1. <map id="messageModelMap" result="MessageModel">
  2. <result property="msgId" column="id"/>
  3. </map>
  • It defines a mapping named messageModelMap. The actual Objective-C object generated is of the MessageModel class.
  • The msgId property of the Objective-C object maps the column value of Column id in the table. Properties not listed are regarded consistent with the column name in the table, thus omitted.

upgrade

 
  1. <upgrade toVersion="1.1">
  2. <step>
  3. alter table...
  4. </step>
  5. <step>
  6. alter table...
  7. </step>
  8. </upgrade>
  • With the version updated, the database may have the demand for upgrade. The SQL statements for upgrade are written here. For example, at the very beginning, the version of the configuration file module is 1.0. After upgrade, the configuration file version is changed to 1.1. When the new version configuration file module runs DAO methods for the first time, it will check the current table version with the configuration file version. With an inconsistency found, it will execute the upgrade step by step. This method is called automatically by the underlying layer. The DAO method will be executed after the upgrade is done.
  • The upgrade is executed according to the SQL UPDATE statement. If there are multiple statements, they can be enclosed by , which is similar to the implementation of .
  • If the operations defined by the upgrade block are required for upgrading the table, the “resetOnUpgrade” argument in the module must be set to “false”.

crypt

 
  1. <crypt class="MessageModel" property="content"/>

It describes that the property of the specified class will be encrypted. When data is written to the database, values fetched from this property will be encrypted. When data is read from the database, the generated object will first decrypt the value before assigning values to the property.

For example, in execution of this DAO method, model is of the MessageModel class. As the content property of model is fetched, the value will be encrypted before being written into the database.

 
  1. <insert id="insertMessage" arguments="model">
  2. insert into ${T} (content) values(#{model.content})
  3. </insert>

The execution of this SELECT method will return an object of the MessageModel class. When the underlying layer fetches data from the database and writes the content property to the MessageModel instance, it will first decrypt the data before writting the data, and then return the ready MessageModel object.

 
  1. <select id="getMessage" arguments="msgId" result="MessageModel">
  2. select * from ${T} where msgId = #{msgId}
  3. </select>

The methods for setting encryption are defined in APDAOProtocol, as follows:

 
  1. /**
  2. * Set an encryptor for encrypting the data in columns marked for encryption in the table. During data writing to the table, data in this column will be encrypted.
  3. *
  4. * @param crypt The encryption struct which will by copied. If the incoming crypt is created externally, it needs to be freed externally. If it is APDefaultEncrypt(), no free is required.
  5. */
  6. - (void)setEncryptMethod:(APDataCrypt*)crypt;
  7. /**
  8. * Set a decryptor for decrypting the data in columns marked for encryption in the table. During data reading from the table, data in this column will be decrypted.
  9. *
  10. * @param crypt The decryption struct which will be copied. If the incoming crypt is created externally, it needs to be freed externally. If it is APDefaultDecrypt(), no free is required.
  11. */
  12. - (void)setDecryptMethod:(APDataCrypt*)crypt;

If no setting is made, the default encryption of APDataCenter will apply. See KV Store.If a DAO proxy object is id<DAOProtocol> And DAOProtocol is @protocol<APDAOProtocol>, Then you can call setEncryptMethod and setDecryptMethod directly with the DAO proxy object to set the encryption and decryption methods.

if

 
  1. <insert id="addMessages" arguments="messages, onlyRead" foreach="messages.model">
  2. <if true="model.read or (not onlyRead)">
  3. insert or replace into ${T} (msgId, content, read) values(#{model.msgId}, #{model.content}, #{model.read})
  4. </if>
  5. </insert>
  • The IF conditional statements can be nested in INSERT, UPFATE, DELETE and SELECT methods. When IF conditions are met, the texts in the IF block will be concatenated into the final SQL statement.

  • The IF can be followed by true=”expr” or false=”expr”. The “expr” stands for expression. It can utilize the argument of the method, and “.” to list the argument object properties to call.

  • Operators supported by the expression are as follows:

    (): brackets

    +: positive sign

    -: negative sign

    +: plus sign

    -: minus sign

    *: multiplication sign

    /: division sign

    \: exact division sign

    %: modulus

    >: greater than

    <: less than

    >=: greater than or equal to

    <=: less than or equal to

    ==: equal to

    ! =: Not equal to

    and: AND, case-insensitive

    or: OR, case-insensitive

    not: NOT, case-insensitive

    xor: exclusive OR, case-insensitive

  • The greater-than sign and less-than sign must be escaped.

  • The arguments inside are names of the incoming arguments from external calls, but do not enclose the arguments with #{} or @{} like in the case of the SQL block.

  • The meaning of nil here is the same as the nil in Objective-C.

  • Strings in the expression should be started or ended with single quotes. Escape characters are not supported, but “\’” is supported to represent a single quote.

  • When the arguments are an Objective-C object, ‘.’ is supported for accessing its property, such as the model.read in the example above. If the argument is an array or dictionary, ‘argument name.count’ can be used to get the element count.

Below is a more complex expression:

 
  1. <if true="(title != nil and year > 2010) or authors.count >= 2">

The title, year and authors are all arguments passed from the caller. A nil value is allowed for title in the call.

The expression above means “when the book title is not empty, and the year of publication is later than 2010, or there are more than 2 authors for the book”.

choose

 
  1. <choose>
  2. <when true="title != nil">
  3. AND title like #{title}
  4. </when>
  5. <when true="author != nil and author.name != nil">
  6. AND author_name like #{author.name}
  7. </when>
  8. <otherwise>
  9. AND featured = 1
  10. </otherwise>
  11. </choose>
  • It implements similar syntax to SWITCH statements, and its expression requirements are similar to the IF statement. The WHEN keyword can also be followed by true="expr" or false="expr".
  • Only the first eligible WHEN or OTHERWISE statement will be executed. The OTHERWISE argument can be void.

foreach

 
  1. <foreach item="iterator" collection="list" open="(" separator="," close=")" reverse="yes">
  2. @{iterator}
  3. </foreach>
  • The open, separator, close, and reverse arguments can be omitted.
  • The item represents the loop variable, and collection represents the argument name of the loop array.

For example, a method receives string array arguments from the outside. The list content is @[@"1", @"2", @"3"]. There is another argument, prefix=@"abc", enclosed by “()”, and separated by “,”. The execution result will be (abc1,abc2,abc3).

 
  1. <update id="proc" arguments="list, prefix">
  2. <foreach item="iterator" collection="list" open="(" separator="," close=")">
  3. {prefix}{iterator}
  4. </foreach>
  5. </update>

Foreach statements are usually used for concatenating the “in” blocks in the SELECT statement, for example:

 
  1. select * from ${T} where id in
  2. <foreach item="id" collection="idList" open="(" separator="," close=")">
  3. #{id}
  4. </foreach>

where, set, trim

 
  1. <where onVoid="quit">
  2. <if true="state != nil">
  3. state = #{state}
  4. </if>
  5. <if true="title != nil">
  6. AND title like #{title}
  7. </if>
  8. <if true="author != nil and author.name != nil">
  9. AND author_name like #{author.name}
  10. </if>
  11. </where>

The WHERE condition will handle superfluous AND and OR (case insensitive) conditions, and it may not return anything when no condition is met, even the WHERE. It is used to concatenate WHERE clauses with a large number of conditions in SQL. As shown in the example above, if only the last judgment is tenable, the statement will correctly return “where author_name like XXX”, instead of “where AND author_name like XXX”.

 
  1. <set>
  2. <if false="username != nil">username=#{username},</if>
  3. <if false="password != nil">password=#{password},</if>
  4. <if true="email != nil">email=#{email},</if>
  5. <if true="bio != nil">bio=#{bio},</if>
  6. </set>

The SET keyword will handle the superfluous “,” signs in the end, and return nothing when no condition is met. It is similar to the WHERE statement, but only that it handles the suffixal commas.

 
  1. <trim prefix="WHERE" prefixOverrides="AND | OR | and | or " onVoid="ignoreAfter">
  2. </trim>
  3. <!--
  4. is equivalent to<where>
  5. -->
  6. <trim prefix="SET" suffixOverrides=",">
  7. </trim>
  8. <!--
  9. is equivalent to<set>
  10. -->
  • The WHERE and SET statements can be replaced by TRIM statements. TRIM statements define the overall prefix of the statement, and the list of superfluous prefixes and suffixes that each clause will handle (divided by “|”).

  • The onVoid argument can appear in WHERE, SET and TRIM statements. It has two values: “ignoreAfter” and “quit”. The values imply the logics used when an empty string is generated because no clause in the TRIM statement is tenable. ignoreAfter means to ignore the following formatting statements and return the current SQL statement for execution, while “quit” means not to execute this SQL statement but to return success.

sql

 
  1. <sql id="userColumns"> id,username,password </sql>
  2. <select id="selectUsers" result="{}">
  3. select ${userColumns}
  4. from some_table
  5. where id = #{id}
  6. </select>

It defines the reusable SQL code segments and uses ${name} to quote the source code segments from other statements.

The name in ${name} cannot be ‘T’ or ‘t’, because ${T}and ${t} represents the default table name. Inside the sql block other sql blocks can be further quoted.

try except

 
  1. <insert id="insertTemplates" arguments="templates" foreach="templates.model">
  2. <try>
  3. insert into ${T} (tplId, tplVersion, time, data, tag) values(%{'#{model.*}', tplId, tplVersion, time, data, tag})
  4. <except>
  5. update ${T} set %{'* = #{model.*}', data, tag} where tplId = #{model.tplId} and tplVersion = #{model.tplVersion}
  6. </except>
  7. </try>
  8. </insert>

Sometimes the same model may be inserted into the database for multiple times. In this case, the INSERT or REPLACE statements will lead to the loss of old data when conflicts occur in the model primary key (another model of the same primary key already exists in the database), and the data is re-inserted. This will lead to changes in the rowid of the same piece of data. The TRY EXCEPT statement block can solve the problem, among others. TRY EXCEPT statements can only be used in definitions of DAO methods and should have no preceding or following statements. Other statement blocks can be included inside the TRY and EXCEPT statements.

During execution of this DAO method, if execution of the TRY statement fails, the execution will move to the EXCEPT statement automatically. Only when both of them fail will this DAO call return the failure result.

Reference methods

@ reference

@{something}: used for method arguments and the argument name is “something”. To format SQL statements, all the object contents will be concatenated into SQL statements. As all the arguments are of the ID type, [NSString stirngWithFormat:@"%@", id] is used by default for formatting. The @{something or ""} format represents that if the incoming argument is nil, it will be converted to an empty string instead of NULL.

We do not recommend@{} for referencing arguments as it is not efficient and subject to the SQL injection risk. If the argument object is of the NSString class, the string will be automatically enclosed in quotes after concatenation to ensure the correctness of the SQL statement format. But if the user has added quotes in the configuration file, the underlying layer will not add the quotes again.

If the @{something no ""} format is adopted, you can enforce not to add quotes.

 
  1. <select id="getMessage" arguments="id" result="[MessageModel]">
  2. select * from ${T} where id = @{id}
  3. </select>

In the example above, the incoming id argument is of the NSString class and the codes above are correct. The generated SQL will format and concatenate the id and enclose it with quotes.

# reference

\#{something} is used for method arguments and the argument name is “something”. To format SQL statements, the argument will be converted to ‘?’ and the object is bound to SQLite. This method is recommended for SQL coding as it is efficient. The#{something or ""} format represents that if the incoming argument is nil, it will be converted to an empty string instead of NULL.

$ reference

${something} is used for referencing contents in the configuration file, such as the default table name ${T} or ${t}, and constants and SQL statement blocks defined in the configuration file.

Chain access

For @ and # references, you can use ‘.’ to list the argument object properties to call. For example, the incoming argument name is “model” of the MessageModel type. It has a property of NSString* content. With @{model.content}, you will be able to fetch the value of its content property. The internal implementation is [NSObject valueForKey:]. So if the argument is a dictionary (The dictionary’s valueForKey is equivalent to [@""]), you can also use #{adict.aaa} to reference the adict[@"aaa"] value.

Delegate method

Each proxy object of generated DAO objects supports APDAOProtocol.

 
  1. @protocol MyDAOOperations <APDAOProtocol>
  2. - (APDAOResult*)insertMessage:(MyMessageModel*)model;
  3. @end

The specific method can be found in function comments in the code.

 
  1. #import <Foundation/Foundation.h>
  2. #import <sqlite3.h>
  3. #import "APDataCrypt.h"
  4. #import "APDAOResult.h"
  5. #import "APDAOTransaction.h"
  6. @protocol APDAOProtocol;
  7. typedef NS_ENUM (NSUInteger, APDAOProxyEventType)
  8. {
  9. APDAOProxyEventShouldUpgrade = 0, // Will be upgraded very soon.
  10. APDAOProxyEventUpgradeFailed, // Table upgrade failed.
  11. APDAOProxyEventTableCreated, // Table is created.
  12. APDAOProxyEventTableDeleted, // Table is deleted.
  13. };
  14. typedef void(^ APDAOProxyEventHandler)(id<APDAOProtocol> proxy, APDAOProxyEventType eventType, NSDictionary* arguments);
  15. /**
  16. * The method defined by this protocol is supported by all the DAP proxy objects. In usage, id<APDAOProtocol> is adopted for converting the DAO object.
  17. */
  18. @protocol APDAOProtocol <NSObject>
  19. /**
  20. * Table names can be set in the configuration file `module`. If you want to use the configuration file as a template for operations on different tables, you can manually design the table names after the DAO object is generated.
  21. * For example, you want to use different tables for conversation messages with different IDs.
  22. */
  23. @property (atomic, strong) NSString* tableName;
  24. /**
  25. * Return the path of the database file where the operated table by the proxy is located.
  26. */
  27. @property (atomic, strong, readonly) NSString* databasePath;
  28. /**
  29. * Acquire the handle of the database file operated table by the proxy.
  30. */
  31. @property (atomic, assign, readonly) sqlite3* sqliteHandle;
  32. /**
  33. * Register the global variable arguments. All the methods in configuration files of the arguments can be used. #{name} and @{name} can be used for accesses in the configuration file.
  34. */
  35. @property (atomic, strong) NSDictionary* globalArguments;
  36. /**
  37. * The event callback of this proxy is set by the business. The callback thread is uncertain.
  38. Pay attention to the circular reference. The business object holds the proxy. Do not access the business object of proxy in this handler method and the proxy can be acquired in the first argument of the callback.
  39. */
  40. @property (atomic, copy) APDAOProxyEventHandler proxyEventHandler;
  41. /**
  42. * Set an encryptor for encrypting the data in columns marked for encryption in the table. During data writing to the table, data in this column will be encrypted.
  43. *
  44. * @param crypt The encryption struct which will be copied. If the incoming crypt is created externally, it needs to be freed externally. If it is APDefaultEncrypt(), no free is required.
  45. */
  46. @property (atomic, assign) APDataCrypt* encryptMethod;
  47. /**
  48. * Set a decryptor for decrypting the data in columns marked for encryption in the table. During data reading from the table, data in this column will be decrypted.
  49. *
  50. * @param crypt The decryption struct which will be copied. If the incoming crypt is created externally, it needs to be freed externally. If it is APDefaultDecrypt(), no free is required.
  51. */
  52. @property (atomic, assign) APDataCrypt* decryptMethod;
  53. /**
  54. * Return the rowId of the last row of SQLite.
  55. *
  56. * @return sqlite3_last_insert_rowid()
  57. */
  58. - (long long)lastInsertRowId;
  59. /**
  60. * Obtain the list of all the methods defined in the configuration file.
  61. */
  62. - (NSArray*)allMethodsList;
  63. /**
  64. * Delete the table defined in the configuration file. It can be used for data recovery under special circumstances. After the table is deleted, the DAO object can still work normally. When other methods are called, new tables will be created.
  65. */
  66. - (APDAOResult*)deleteTable;
  67. /**
  68. * Delete all the tables conforming to a regular expression rule. Make sure you delete tables operated by this proxy only, otherwise exceptions may occur.
  69. *
  70. * @param pattern Regular expression
  71. * @param autovacuum After the deletion is complete, whether to call “vacuum” to clear the database space.
  72. * @param progress Progress callback. Nil value is allowed. The callback is not guaranteed to be in the main thread. It is a percentage value.
  73. *
  74. * @return Whether the operation is successful.
  75. */
  76. - (APDAOResult*)deleteTablesWithRegex:(NSString*)pattern autovacuum:(BOOL)autovacuum progress:(void(^)(float progress))progress;
  77. /**
  78. * Call the database link of your own to excecute the “vacuum” operation.
  79. */
  80. - (void)vacuumDatabase;
  81. /**
  82. * DAO objects can put their operations in transactions to speed up the operation. So in fact, you call the daoTransaction method of the database file APSharedPreferences that this DAO object operates on.
  83. */
  84. - (APDAOResult*)daoTransaction:(APDAOTransaction)transaction;
  85. /**
  86. * Create a parallel connection for the database, for the purpose of speeding up the possible concurrent SELECT operations that may follow. This method can be called for multiple times to create several stand-by connections for the database.
  87. * The connections created will be automatically closed and the business layer does not to handle them.
  88. * @param autoclose Automatically close the connections if they are idle for a certain number of seconds. The value "0" indicates that the system value will be used.
  89. */
  90. - (void)prepareParallelConnection:(NSTimeInterval)autoclose;
  91. @end