Advertisement
ridjis

PostsDatabaseHelper

Oct 31st, 2015
339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.69 KB | None | 0 0
  1. public class PostsDatabaseHelper extends SQLiteOpenHelper {
  2.     // Database Info
  3.     private static final String DATABASE_NAME = "postsDatabase";
  4.     private static final int DATABASE_VERSION = 1;
  5.  
  6.     // Table Names
  7.     private static final String TABLE_POSTS = "posts";
  8.     private static final String TABLE_USERS = "users";
  9.  
  10.     // Post Table Columns
  11.     private static final String KEY_POST_ID = "id";
  12.     private static final String KEY_POST_USER_ID_FK = "userId";
  13.     private static final String KEY_POST_TEXT = "text";
  14.  
  15.     // User Table Columns
  16.     private static final String KEY_USER_ID = "id";
  17.     private static final String KEY_USER_NAME = "userName";
  18.     private static final String KEY_USER_PROFILE_PICTURE_URL = "profilePictureUrl";
  19.  
  20.     private static PostsDatabaseHelper sInstance;
  21.  
  22.     public static synchronized PostsDatabaseHelper getInstance(Context context) {
  23.         // Use the application context, which will ensure that you
  24.         // don't accidentally leak an Activity's context.
  25.         // See this article for more information: http://bit.ly/6LRzfx
  26.         if (sInstance == null) {
  27.             sInstance = new PostsDatabaseHelper(context.getApplicationContext());
  28.         }
  29.         return sInstance;
  30.     }
  31.  
  32.     /**
  33.      * Constructor should be private to prevent direct instantiation.
  34.      * Make a call to the static method "getInstance()" instead.
  35.      */
  36.     private PostsDatabaseHelper(Context context) {
  37.         super(context, DATABASE_NAME, null, DATABASE_VERSION);
  38.     }
  39.  
  40.     // Called when the database connection is being configured.
  41.     // Configure database settings for things like foreign key support, write-ahead logging, etc.
  42.     @Override
  43.     public void onConfigure(SQLiteDatabase db) {
  44.         super.onConfigure(db);
  45.         db.setForeignKeyConstraintsEnabled(true);
  46.     }
  47.  
  48.     // Called when the database is created for the FIRST time.
  49.     // If a database already exists on disk with the same DATABASE_NAME, this method will NOT be called.
  50.     @Override
  51.     public void onCreate(SQLiteDatabase db) {
  52.         String CREATE_POSTS_TABLE = "CREATE TABLE " + TABLE_POSTS +
  53.                 "(" +
  54.                     KEY_POST_ID + " INTEGER PRIMARY KEY," + // Define a primary key
  55.                     KEY_POST_USER_ID_FK + " INTEGER REFERENCES " + TABLE_USERS + "," + // Define a foreign key
  56.                     KEY_POST_TEXT + " TEXT" +
  57.                 ")";
  58.  
  59.         String CREATE_USERS_TABLE = "CREATE TABLE " + TABLE_USERS +
  60.                 "(" +
  61.                     KEY_USER_ID + " INTEGER PRIMARY KEY," +
  62.                     KEY_USER_NAME + " TEXT," +
  63.                     KEY_USER_PROFILE_PICTURE_URL + " TEXT" +
  64.                 ")";
  65.  
  66.         db.execSQL(CREATE_POSTS_TABLE);
  67.         db.execSQL(CREATE_USERS_TABLE);
  68.     }
  69.  
  70.     // Called when the database needs to be upgraded.
  71.     // This method will only be called if a database already exists on disk with the same DATABASE_NAME,
  72.     // but the DATABASE_VERSION is different than the version of the database that exists on disk.
  73.     @Override
  74.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  75.         if (oldVersion != newVersion) {
  76.             // Simplest implementation is to drop all old tables and recreate them
  77.             db.execSQL("DROP TABLE IF EXISTS " + TABLE_POSTS);
  78.             db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
  79.             onCreate(db);
  80.         }
  81.     }
  82.  
  83.     // Insert a post into the database
  84.     public void addPost(Post post) {
  85.         // Create and/or open the database for writing
  86.         SQLiteDatabase db = getWritableDatabase();
  87.  
  88.         // It's a good idea to wrap our insert in a transaction. This helps with performance and ensures
  89.         // consistency of the database.
  90.         db.beginTransaction();
  91.         try {
  92.             // The user might already exist in the database (i.e. the same user created multiple posts).
  93.             long userId = addorUpdateUser(post.user);
  94.  
  95.             ContentValues values = new ContentValues();
  96.             values.put(KEY_POST_USER_ID_FK, userId);
  97.             values.put(KEY_POST_TEXT, post.text);
  98.  
  99.             // Notice how we haven't specified the primary key. SQLite auto increments the primary key column.
  100.             db.insertOrThrow(TABLE_POSTS, null, values);
  101.             db.setTransactionSuccessful();
  102.         } catch (Exception e) {
  103.             Log.d(TAG, "Error while trying to add post to database");
  104.         } finally {
  105.             db.endTransaction();
  106.         }
  107.     }
  108.  
  109.     // Insert or update a user in the database
  110.     // Since SQLite doesn't support "upsert" we need to fall back on an attempt to UPDATE (in case the
  111.     // user already exists) optionally followed by an INSERT (in case the user does not already exist).
  112.     // Unfortunately, there is a bug with the insertOnConflict method
  113.     // (https://code.google.com/p/android/issues/detail?id=13045) so we need to fall back to the more
  114.     // verbose option of querying for the user's primary key if we did an update.
  115.     public long addorUpdateUser(User user) {
  116.         // The database connection is cached so it's not expensive to call getWriteableDatabase() multiple times.
  117.         SQLiteDatabase db = getWritableDatabase();
  118.         long userId = -1;
  119.  
  120.         db.beginTransaction();
  121.         try {
  122.             ContentValues values = new ContentValues();
  123.             values.put(KEY_USER_NAME, user.userName);
  124.             values.put(KEY_USER_PROFILE_PICTURE_URL, user.profilePictureUrl);
  125.  
  126.             // First try to update the user in case the user already exists in the database
  127.             // This assumes userNames are unique
  128.             int rows = db.update(TABLE_USERS, values, KEY_USER_NAME + "= ?", new String[]{user.userName});
  129.  
  130.             // Check if update succeeded
  131.             if (rows == 1) {
  132.                 // Get the primary key of the user we just updated
  133.                 String usersSelectQuery = String.format("SELECT %s FROM %s WHERE %s = ?",
  134.                         KEY_USER_ID, TABLE_USERS, KEY_USER_NAME);
  135.                 Cursor cursor = db.rawQuery(usersSelectQuery, new String[]{String.valueOf(user.userName)});
  136.                 try {
  137.                     if (cursor.moveToFirst()) {
  138.                         userId = cursor.getInt(0);
  139.                         db.setTransactionSuccessful();
  140.                     }
  141.                 } finally {
  142.                     if (cursor != null && !cursor.isClosed()) {
  143.                         cursor.close();
  144.                     }
  145.                 }
  146.             } else {
  147.                 // user with this userName did not already exist, so insert new user
  148.                 userId = db.insertOrThrow(TABLE_USERS, null, values);
  149.                 db.setTransactionSuccessful();
  150.             }
  151.         } catch (Exception e) {
  152.             Log.d(TAG, "Error while trying to add or update user");
  153.         } finally {
  154.             db.endTransaction();
  155.         }
  156.         return userId;
  157.     }
  158.  
  159.     // Get all posts in the database
  160.     public List<Post> getAllPosts() {
  161.         List<Post> posts = new ArrayList<>();
  162.  
  163.         // SELECT * FROM POSTS
  164.         // LEFT OUTER JOIN USERS
  165.         // ON POSTS.KEY_POST_USER_ID_FK = USERS.KEY_USER_ID
  166.         String POSTS_SELECT_QUERY =
  167.                 String.format("SELECT * FROM %s LEFT OUTER JOIN %s ON %s.%s = %s.%s",
  168.                         TABLE_POSTS,
  169.                         TABLE_USERS,
  170.                         TABLE_POSTS, KEY_POST_USER_ID_FK,
  171.                         TABLE_USERS, KEY_USER_ID);
  172.  
  173.         // "getReadableDatabase()" and "getWriteableDatabase()" return the same object (except under low
  174.         // disk space scenarios)
  175.         SQLiteDatabase db = getReadableDatabase();
  176.         Cursor cursor = db.rawQuery(POSTS_SELECT_QUERY, null);
  177.         try {
  178.             if (cursor.moveToFirst()) {
  179.                 do {
  180.                     User newUser = new User();
  181.                     newUser.userName = cursor.getString(cursor.getColumnIndex(KEY_USER_NAME));
  182.                     newUser.profilePictureUrl = cursor.getString(cursor.getColumnIndex(KEY_USER_PROFILE_PICTURE_URL));
  183.  
  184.                     Post newPost = new Post();
  185.                     newPost.text = cursor.getString(cursor.getColumnIndex(KEY_POST_TEXT));
  186.                     newPost.user = newUser;
  187.                     posts.add(newPost);
  188.                 } while(cursor.moveToNext());
  189.             }
  190.         } catch (Exception e) {
  191.             Log.d(TAG, "Error while trying to get posts from database");
  192.         } finally {
  193.             if (cursor != null && !cursor.isClosed()) {
  194.                 cursor.close();
  195.             }
  196.         }
  197.         return posts;
  198.     }
  199.  
  200.     // Update the user's profile picture url
  201.     public int updateUserProfilePicture(User user) {
  202.         SQLiteDatabase db = this.getWritableDatabase();
  203.  
  204.         ContentValues values = new ContentValues();
  205.         values.put(KEY_USER_PROFILE_PICTURE_URL, user.profilePictureUrl);
  206.  
  207.         // Updating profile picture url for user with that userName
  208.         return db.update(TABLE_USERS, values, KEY_USER_NAME + " = ?",
  209.                 new String[] { String.valueOf(user.userName) });
  210.     }
  211.  
  212.     // Delete all posts and users in the database
  213.     public void deleteAllPostsAndUsers() {
  214.         SQLiteDatabase db = getWritableDatabase();
  215.         db.beginTransaction();
  216.         try {
  217.             // Order of deletions is important when foreign key relationships exist.
  218.             db.delete(TABLE_POSTS, null, null);
  219.             db.delete(TABLE_USERS, null, null);
  220.             db.setTransactionSuccessful();
  221.         } catch (Exception e) {
  222.             Log.d(TAG, "Error while trying to delete all posts and users");
  223.         } finally {
  224.             db.endTransaction();
  225.         }
  226.     }    
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement