Finally got around to describe the changes that have occurred in the
AnnotatedSQL library.
Announcement:
1. Plugin Changes
2. Changes in schema annotations
3. What is the content provider in my understanding
4. We generate content provider according to the scheme
1. Plugin
Plugin update site
Now this is a full plug-in for Eclipse with its own
update site.Build path-> Libraries-> Add Library
Annotations now do not need to put in the project, the plugin carries them with you. You just need to add AnnotatedSQL Libaray to the project in the project properties. And you will always have the API corresponding to the plugin.
')
Templates for creating a schema, table, view
In eclipse there is such a wonderful thing as code templates. The plugin adds its own templates for creating a schema, table, view. and these templates fall into the code completion, the one that is shown by ctrl + space
For example, we write
Tabl, press the cherished buttons and see
Table - AnnotatedSQL , we also select a template for your table.
Do not forget: in order to jump into the next field editing a template, press the “Tab” key, and “Enter” will finish editing the template.
2. Updates in the schema
Perhaps only one abstract has changed.Join
Renamed attributes:
srcTable ->
joinTablesrcColumn ->
joinColumndestTable ->
onTableAliasdestColumn ->
onColumnI hope it will be clearer. And the main thing to remember is that
onTableAlias is not a table name, but an alias to it.
And several were added at once:Rawjoin
If the ON condition is different from column1 = column2 then you should go here. You specify the table that joins and write the condition with your hands.
Attributes:joinTable - the name of the table that you want to join
onCondition - ON condition
IgnoreColumns
When we do not need to select a single column from a table, we mark it with such annotation. Applicable for
From ,
Join ,
RawJoinRawquuery
Request with parameters anywhere. This piece was invented for the content provider and due to the limited view in sql. The view is select + join, and where is applied later.
But often you need to execute the query, where already in the ON condition of the join you need to use the parameters. for this purpose it is invented, ala sql function. Where you need to use the parameters naturally set
?The resulting sql request is not going anywhere just lies constant and you can pull it by the URI (I will tell further)
RawQuery can be formed like SimpleView using
From ,
Join and
RawJoin ,
and I can use "raw sql" through the
SqlQuery annotation
@RawQuery(ChatListQuery.QUERY_NAME) public static interface ChatListQuery{ String QUERY_NAME = "chatListQuery"; @SqlQuery String CHAT_LIST_QUERY = " some sql here" }
3. What is the content provider in my understanding
Based on the experience of developing for Android, the content provider should have additional properties. And additional parameters can be pushed through Uri, there is a lot of “free space” - fragment, parametrs are all like in url. So, this is what you usually need:
no-notifyWhen you insert a packet of data into the provider, there is no need to notify the UI after inserting each row, but rather zanotypit after insertion.
alternative notify uriOften there is a need when notifying one uri to decipher dependent uri. For example, you have a UserView that you use to populate the list, and the insertion then goes into the User table and you need to notify uri from the view, this is the alternative uri.
limittrivial limit on request
4. Generation of Content Provider according to the scheme
After I wrote the autogeneration scheme for annotations, I wondered: I have everything to
capture the world to generate content provider and make my life easier. No sooner said than done. A couple of annotations and you have a full-fledged provider + some goodies. Well, it started!
First, I must say that the content provider is a generic provider. This will help us annotation
ProviderProvider
name - class name for content provider
authority - we need to know the authority context of the provider.
schemaClass is the name of the schema class. Used when the open helper is generated.
openHelperClass - you can refuse to generate an internal open helper and force yours to use.
@Schema(className="FManagerSchema", dbName="fmanager.db", dbVersion=6) @Provider(authority="com.gdubina.fmanager.store.FManagerProvider", schemaClass="FManagerSchema", name="FManagerProvider", openHelperClass="CustomOpenHelper") public interface FManagerStore {
So, we said we want a content provider. What's next?
I must say by what URI our entity will be available - we use the same
URI annotation
URI
We hang on a constant in the table, view or query. I like something like URI_CONTENT.
All attributes here are optional, but they are.
type - type uri. As we know in the content provider, it is customary to determine that many entries are returned by a URI (dir) or one (item). Remember this
getType method? here is the same.
onlyQuery - access only for query execution, usable for view and query. At attempt to execute insert / delete / update - will lead to exception
column - the default is "_id". Actually, when you use the URI of the parh / # content provider, it makes the selection ala _id = uri.getLastPathSegment (). so here you can override what field to do select
altNotify - a list of uri that need to be speeded up
A couple of examples:this is how we forced the content provider to work with the championship table. Everything is available - select, insert, delete, update
@Table(ChempTable.TABLE_NAME) public static interface ChempTable{ @URI String CONTENT_PATH = "chemps"; String TABLE_NAME = "chemp_table"; @PrimaryKey @Column(type = Type.INTEGER) String ID = "_id"; @Column(type = Type.TEXT) String TITLE = "title"; @Column(type = Type.TEXT) String CHEMP_KEY = "CHEMP_KEY"; }
And here is a piece of the message table. As we can see, here I have two URIs.
1. to access the URI_CONTENT table itself
2. to select messages of a certain user URI_MESSAGES_BY_USER, just here column = Message.FROM_ID
@Table(Message.TABLE_NAME) @PrimaryKey(columns = {Message.USER_ID, Message.ID}) public static interface Message{ @URI(altNotify={MessageChatView.URI_CONTENT, ChatListQuery.URI_CONTENT, URI_RECALC_MESSAGE_PATH}) String URI_CONTENT = "message"; @URI(type=URI.Type.ITEM, altNotify={Message.URI_CONTENT, MessageChatView.URI_CONTENT, ChatListQuery.URI_CONTENT, URI_RECALC_MESSAGE_PATH}, column=Message.FROM_ID) String URI_MESSAGES_BY_USER = "message_by_user"; }
To create a simple task provider, this is enough. Only two annotations!
But this is not all, what to do if you need to do something about actions with a table? for example, added a user - let's go upload an avatar. in large sql there is such a thing as triggers - they do something similar. So I called my annotation as
Trigger itself. The provider will create a protected method that you must override to the heirs of the autogenerated class.
Trigger
hangs on the uri, but the method call occurs when the table name matches
name - the name of the trigger, used to generate the name of the method
when - when to call the method before the action with the table or after.
type - what actions to respond - insert / delete / udapte or all at once
Method name generated by this pattern
on<Name><When>Inserted(ContentValues values){} on<Name><When>Deleted(Uri uri, String selection, String[] selectionArgs){} on<Name><When>Updated(Uri uri, ContentValues values, String selection, String[] selectionArg){}
If you need to hang several triggers, use the
Triggers annotation and fill it with triggers.
Example:
@Table(User.TABLE_NAME) public static interface User{ @Trigger(type=Trigger.Type.INSERT, name="user", when=When.BEFORE) @URI(altNotify={SuggestionView.URI_CONTENT, MessageChatView.URI_CONTENT, ChatListQuery.URI_CONTENT}) String URI_CONTENT = "user";
and here is what the provider looks like in this case
public class AppProvider extends AppAutoProvider { @Override protected void onUserBeforeInserted(ContentValues values) { ................. }
How to use notify correctly?
If you want to type uri and all alternatives, you must use the static method
notifyUri(ContentResolver cr, Uri uri)
Bundle statically method from provider
getContentUri(String path)
- by path we get the URI
getContentUriGroupBy(String path, String groupBy)
- by path we get the URI with grouping support
getContentUri(String path, long id)
- we get the URI path / #
getContentUri(String path, String id)
- we get the URI path / #
getContentWithLimitUri(String path, int limit)
- path + limit
getNoNotifyContentUri(String path)
- by path we get the URI without notifying
getNoNotifyContentUri(String path, long id)
- we get the URI path / # without notifying
PS library has passed "combat" tests and has already been used in production projects.
PSS for grammar and spelling please do not kick