1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package androidx.room.integration.testapp.database; 17 18 import androidx.annotation.NonNull; 19 import androidx.paging.DataSource; 20 import androidx.paging.ItemKeyedDataSource; 21 import androidx.room.InvalidationTracker; 22 23 import java.util.Collections; 24 import java.util.List; 25 import java.util.Set; 26 27 /** 28 * Sample Room keyed data source. 29 */ 30 public class LastNameAscCustomerDataSource extends ItemKeyedDataSource<String, Customer> { 31 private final CustomerDao mCustomerDao; 32 @SuppressWarnings("FieldCanBeLocal") 33 private final InvalidationTracker.Observer mObserver; 34 private SampleDatabase mDb; 35 factory(final SampleDatabase db)36 public static Factory<String, Customer> factory(final SampleDatabase db) { 37 return new Factory<String, Customer>() { 38 @Override 39 public DataSource<String, Customer> create() { 40 return new LastNameAscCustomerDataSource(db); 41 } 42 }; 43 } 44 45 /** 46 * Create a DataSource from the customer table of the given database 47 */ 48 private LastNameAscCustomerDataSource(SampleDatabase db) { 49 mDb = db; 50 mCustomerDao = db.getCustomerDao(); 51 mObserver = new InvalidationTracker.Observer("customer") { 52 @Override 53 public void onInvalidated(@NonNull Set<String> tables) { 54 invalidate(); 55 } 56 }; 57 db.getInvalidationTracker().addWeakObserver(mObserver); 58 } 59 60 @Override 61 public boolean isInvalid() { 62 mDb.getInvalidationTracker().refreshVersionsSync(); 63 return super.isInvalid(); 64 } 65 66 @NonNull 67 public static String getKeyStatic(@NonNull Customer customer) { 68 return customer.getLastName(); 69 } 70 71 @NonNull 72 @Override 73 public String getKey(@NonNull Customer customer) { 74 return getKeyStatic(customer); 75 } 76 77 @Override 78 public void loadInitial(@NonNull LoadInitialParams<String> params, 79 @NonNull LoadInitialCallback<Customer> callback) { 80 String customerName = params.requestedInitialKey; 81 List<Customer> list; 82 if (customerName != null) { 83 // initial keyed load - load before 'customerName', 84 // and load after last item in before list 85 int pageSize = params.requestedLoadSize / 2; 86 String key = customerName; 87 list = mCustomerDao.customerNameLoadBefore(key, pageSize); 88 Collections.reverse(list); 89 if (!list.isEmpty()) { 90 key = getKey(list.get(list.size() - 1)); 91 } 92 list.addAll(mCustomerDao.customerNameLoadAfter(key, pageSize)); 93 } else { 94 list = mCustomerDao.customerNameInitial(params.requestedLoadSize); 95 } 96 97 if (params.placeholdersEnabled && !list.isEmpty()) { 98 String firstKey = getKey(list.get(0)); 99 String lastKey = getKey(list.get(list.size() - 1)); 100 101 // only bother counting if placeholders are desired 102 final int position = mCustomerDao.customerNameCountBefore(firstKey); 103 final int count = position + list.size() + mCustomerDao.customerNameCountAfter(lastKey); 104 callback.onResult(list, position, count); 105 } else { 106 callback.onResult(list); 107 } 108 } 109 110 @Override 111 public void loadAfter(@NonNull LoadParams<String> params, 112 @NonNull LoadCallback<Customer> callback) { 113 callback.onResult(mCustomerDao.customerNameLoadAfter(params.key, params.requestedLoadSize)); 114 } 115 116 @Override 117 public void loadBefore(@NonNull LoadParams<String> params, 118 @NonNull LoadCallback<Customer> callback) { 119 List<Customer> list = mCustomerDao.customerNameLoadBefore( 120 params.key, params.requestedLoadSize); 121 Collections.reverse(list); 122 callback.onResult(list); 123 } 124 } 125 126