Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relations example! #494

Merged
merged 1 commit into from
Aug 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.entity.Tweet;
import com.pushtorefresh.storio.sample.db.entity.TweetStorIOSQLiteDeleteResolver;
import com.pushtorefresh.storio.sample.db.entity.TweetStorIOSQLiteGetResolver;
import com.pushtorefresh.storio.sample.db.entity.TweetStorIOSQLitePutResolver;
import com.pushtorefresh.storio.sample.db.entities.Tweet;
import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLiteDeleteResolver;
import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLiteGetResolver;
import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLitePutResolver;
import com.pushtorefresh.storio.sample.db.entities.TweetWithUser;
import com.pushtorefresh.storio.sample.db.entities.User;
import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLiteDeleteResolver;
import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLiteGetResolver;
import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLitePutResolver;
import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserDeleteResolver;
import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserGetResolver;
import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserPutResolver;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
Expand All @@ -24,6 +32,7 @@ public class DbModule {
// It's thread safe and so on, so just share it.
// But if you need you can have multiple instances of StorIO
// (SQLite or ContentResolver) with different settings such as type mapping, logging and so on.
// But keep in mind that different instances of StorIOSQLite won't share notifications!
@Provides
@NonNull
@Singleton
Expand All @@ -35,13 +44,23 @@ public StorIOSQLite provideStorIOSQLite(@NonNull SQLiteOpenHelper sqLiteOpenHelp
.getResolver(new TweetStorIOSQLiteGetResolver())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

damn

.deleteResolver(new TweetStorIOSQLiteDeleteResolver())
.build())
.addTypeMapping(User.class, SQLiteTypeMapping.<User>builder()
.putResolver(new UserStorIOSQLitePutResolver())
.getResolver(new UserStorIOSQLiteGetResolver())
.deleteResolver(new UserStorIOSQLiteDeleteResolver())
.build())
.addTypeMapping(TweetWithUser.class, SQLiteTypeMapping.<TweetWithUser>builder()
.putResolver(new TweetWithUserPutResolver())
.getResolver(new TweetWithUserGetResolver())
.deleteResolver(new TweetWithUserDeleteResolver())
.build())
.build();
}

@Provides
@NonNull
@Singleton
public SQLiteOpenHelper provideSQSqLiteOpenHelper(@NonNull Context context) {
public SQLiteOpenHelper provideSQLiteOpenHelper(@NonNull Context context) {
return new DbOpenHelper(context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,19 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.table.TweetTableMeta;
import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sample.db.tables.UsersTable;

public class DbOpenHelper extends SQLiteOpenHelper {

public DbOpenHelper(@NonNull Context context) {
super(context, "sample_db", null, 1);
}

// Better than static final field -> allows VM to unload useless String
// Because you need this string only once per application life on the device
@NonNull
private static String getCreateTweetTableQuery() {
return "CREATE TABLE " + TweetTableMeta.TABLE + "("
+ TweetTableMeta.COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, "
+ TweetTableMeta.COLUMN_AUTHOR + " TEXT NOT NULL, "
+ TweetTableMeta.COLUMN_CONTENT + " TEXT NOT NULL"
+ ");";
}

@Override
public void onCreate(@NonNull SQLiteDatabase db) {
db.execSQL(getCreateTweetTableQuery());
db.execSQL(TweetsTable.getCreateTableQuery());
db.execSQL(UsersTable.getCreateTableQuery());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.pushtorefresh.storio.sample.db.entity;
package com.pushtorefresh.storio.sample.db.entities;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;

Expand All @@ -12,22 +13,22 @@
// This annotation will trigger annotation processor
// Which will generate type mapping code in compile time,
// You just need to link it in your code.
@StorIOSQLiteType(table = "tweets")
@StorIOSQLiteType(table = TweetsTable.TABLE)
public class Tweet {

/**
* If object was not inserted into db, id will be null
*/
@Nullable
@StorIOSQLiteColumn(name = "_id", key = true)
@StorIOSQLiteColumn(name = TweetsTable.COLUMN_ID, key = true)
Long id;

@NonNull
@StorIOSQLiteColumn(name = "author")
@StorIOSQLiteColumn(name = TweetsTable.COLUMN_AUTHOR)
String author;

@NonNull
@StorIOSQLiteColumn(name = "content")
@StorIOSQLiteColumn(name = TweetsTable.COLUMN_CONTENT)
String content;

// leave default constructor for AutoGenerated code!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.pushtorefresh.storio.sample.db.entities;

import android.support.annotation.NonNull;

/**
* Example of entity with another entity linked together!
*
* But our Annotation Processor can not handle such things,
* so we need to wrote our own PutResolver, GetResolver and DeleteResolver
*/
public class TweetWithUser {

@NonNull
private final Tweet tweet;

@NonNull
private final User user;

public TweetWithUser(@NonNull Tweet tweet, @NonNull User user) {
this.tweet = tweet;
this.user = user;
}

@NonNull
public Tweet tweet() {
return tweet;
}

@NonNull
public User user() {
return user;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.pushtorefresh.storio.sample.db.entities;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.pushtorefresh.storio.sample.db.tables.UsersTable;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;

// This annotation will trigger annotation processor
// Which will generate type mapping code in compile time,
// You just need to link it in your code.
@StorIOSQLiteType(table = UsersTable.TABLE)
public class User {

/**
* If object was not inserted into db, id will be null
*/
@Nullable
@StorIOSQLiteColumn(name = UsersTable.COLUMN_ID, key = true)
Long id;

// For example: "artem_zin", without "@".
@NonNull
@StorIOSQLiteColumn(name = UsersTable.COLUMN_NICK)
String nick;

// leave default constructor for AutoGenerated code!
User() {

}

@NonNull
public static User newUser(@Nullable Long id, @NonNull String nick) {
User user = new User();
user.id = id;
user.nick = nick;
return user;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.pushtorefresh.storio.sample.db.resolvers;

import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.entities.TweetWithUser;
import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sample.db.tables.UsersTable;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResolver;
import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;

import java.util.HashSet;
import java.util.Set;

import static java.util.Arrays.asList;

public class TweetWithUserDeleteResolver extends DeleteResolver<TweetWithUser> {
@NonNull
@Override
public DeleteResult performDelete(@NonNull StorIOSQLite storIOSQLite, @NonNull TweetWithUser tweetWithUser) {
// We can even reuse StorIO methods
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

storIOSQLite
.delete()
.objects(asList(tweetWithUser.tweet(), tweetWithUser.user()))
.prepare() // BTW: it will use transaction!
.executeAsBlocking();

final Set<String> affectedTables = new HashSet<String>(2);

affectedTables.add(TweetsTable.TABLE);
affectedTables.add(UsersTable.TABLE);

return DeleteResult.newInstance(2, affectedTables);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.pushtorefresh.storio.sample.db.resolvers;


import android.database.Cursor;
import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.entities.Tweet;
import com.pushtorefresh.storio.sample.db.entities.TweetWithUser;
import com.pushtorefresh.storio.sample.db.entities.User;
import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sample.db.tables.UsersTable;
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver;

public class TweetWithUserGetResolver extends DefaultGetResolver<TweetWithUser> {

// We expect that cursor will contain both Tweet and User: SQL JOIN
@NonNull
@Override
public TweetWithUser mapFromCursor(@NonNull Cursor cursor) {
final Tweet tweet = Tweet.newTweet(
cursor.getLong(cursor.getColumnIndexOrThrow(TweetsTable.COLUMN_ID)),
cursor.getString(cursor.getColumnIndexOrThrow(TweetsTable.COLUMN_AUTHOR)),
cursor.getString(cursor.getColumnIndexOrThrow(TweetsTable.COLUMN_CONTENT))
);

final User user = User.newUser(
cursor.getLong(cursor.getColumnIndexOrThrow(UsersTable.COLUMN_ID)),
cursor.getString(cursor.getColumnIndexOrThrow(UsersTable.COLUMN_NICK))
);

return new TweetWithUser(tweet, user);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.pushtorefresh.storio.sample.db.resolvers;

import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.entities.TweetWithUser;
import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sample.db.tables.UsersTable;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver;
import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;

import java.util.HashSet;
import java.util.Set;

import static java.util.Arrays.asList;

public class TweetWithUserPutResolver extends PutResolver<TweetWithUser> {

@NonNull
@Override
public PutResult performPut(@NonNull StorIOSQLite storIOSQLite, @NonNull TweetWithUser tweetWithUser) {
// We can even reuse StorIO methods
final PutResults<Object> putResults = storIOSQLite
.put()
.objects(asList(tweetWithUser.tweet(), tweetWithUser.user()))
.prepare() // BTW: it will use transaction!
.executeAsBlocking();

final Set<String> affectedTables = new HashSet<String>(2);

affectedTables.add(TweetsTable.TABLE);
affectedTables.add(UsersTable.TABLE);

// Actually, it's not very clear what PutResult should we return here…
// Because there is no table for this pair of tweet and user
// So, let's just return Update Result
return PutResult.newUpdateResult(putResults.numberOfUpdates(), affectedTables);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.pushtorefresh.storio.sample.db.table;
package com.pushtorefresh.storio.sample.db.tables;

import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sqlite.queries.Query;

// We suggest to store table meta such as table name, columns names, queries, etc in separate class
// Because it makes code of the Entity itself cleaner and easier to read/understand/support
public class TweetTableMeta {
public class TweetsTable {

@NonNull
public static final String TABLE = "tweets";
Expand All @@ -33,7 +33,18 @@ public class TweetTableMeta {
.build();

// This is just class with Meta Data, we don't need instances
private TweetTableMeta() {
private TweetsTable() {
throw new IllegalStateException("No instances please");
}

// Better than static final field -> allows VM to unload useless String
// Because you need this string only once per application life on the device
@NonNull
public static String getCreateTableQuery() {
return "CREATE TABLE " + TABLE + "("
+ COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, "
+ COLUMN_AUTHOR + " TEXT NOT NULL, "
+ COLUMN_CONTENT + " TEXT NOT NULL"
+ ");";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.pushtorefresh.storio.sample.db.tables;

import android.support.annotation.NonNull;

// We suggest to store table meta such as table name, columns names, queries, etc in separate class
// Because it makes code of the Entity itself cleaner and easier to read/understand/support
public class UsersTable {

@NonNull
public static final String TABLE = "users";

@NonNull
public static final String COLUMN_ID = "_id";

@NonNull
public static final String COLUMN_NICK = "nick";

// This is just class with Meta Data, we don't need instances
private UsersTable() {
throw new IllegalStateException("No instances please");
}

// Better than static final field -> allows VM to unload useless String
// Because you need this string only once per application life on the device
@NonNull
public static String getCreateTableQuery() {
return "CREATE TABLE " + TABLE + "("
+ COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, "
+ COLUMN_NICK + " TEXT NOT NULL UNIQUE"
+ ");";
}
}
Loading