I am not familiar with Room Database. I want to clear the data from some tables when I click on button. I have the similar code in IOS but I am not sure where I have to write this method and call this delete function and how to access the tables. Can anyone help me on this in android.
IOS code:
class ApplicationResetManager: NSObject {
static let shared: ApplicationResetManager = ApplicationResetManager()
var cloSuccess:((_ isSuccessfull: Bool)->Void)?
func clearAllData(completion: (Bool) -> Void) {
let isSyncGoingOn = ApplicationManager.shared.isSyncGoingOn
if let currentUser = ApplicationManager.shared.currentUser, currentUser.id! > 0, isSyncGoingOn == false {
let dbQueue = DatabaseManager.shared.dbQueue!
do {
// 4. Access the database
try dbQueue.inTransaction { db in
do {
try UserLocations.deleteAll(db)
try LineLayoutEquipment.deleteAll(db)
try LineLayout.deleteAll(db)
try Survey.deleteAll(db)
try HealthCheck.deleteAll(db)
try HealthCheckData.deleteAll(db)
try ActionItem.deleteAll(db)
try Equipments.deleteAll(db)
try EquipmentIndustry.deleteAll(db)
try Comments.deleteAll(db)
try PlantAreas.deleteAll(db)
try PlantAreasIndustrys.deleteAll(db)
try Applications.deleteAll(db)
try ApplicationsIndustrys.deleteAll(db)
try SurveyLineLevel.deleteAll(db)
try HealthCheckLineLevel.deleteAll(db)
try ActionItemLineLevel.deleteAll(db)
try ActionItemLineLvlComments.deleteAll(db)
UserDefaults.standard.set([], forKey: arr_selected_company)
ApplicationManager.shared.currentUser.defaultCompanyId = nil
completion(true)
return .commit
} catch {
completion(false)
return .rollback
}
}
} catch {
completion(false)
}
} else {
print("Sync is already in progress")
}
}
}
If using Room you would have
@Entity
annotated classes (the tables),
a single @Database
annotated class per database (very probably just the 1) that:-
1.describes the database (list of entities (i.e. tables aka @Entity
annotated class(es)) via the entities
parameter)
@Dao
annotated (interface(s) or abstract class(es))One or more @Dao
annotated interfaces and/or abstract classes which
@Insert
, @Delete
, @Update
) and @Query
methods.As you appear to want to do many things in a single transaction, the you would want a method that invokes those many actions.
An interface cannot have methods with functions, therefore you would need an @Dao
annotated class.
The actual, do many things method is a little bit of a trick.
You first of all have an @Transaction
annotation. As room doesn't appear to consider this annotation unless you are using one of the annotations (and the only one that can be tailored is @Query
), then you tell Room to run a query that does nothing i.e. use @Query("")
.
The you define the method with the body that can invoke other methods in the @Dao
annotated abstract class.
So you your code could be along the lines of:-
@Dao
abstract class MyDoitAllStuffDao {
@Query("DELETE FROM userLocations") /* no WHERE clauses = delete all rows. TO BE USED IN DO IT ALL METHOD*/
int deleteAllUserLocations();
@Query("DELETE FROM linelayoutequipment");
int deleteAllLineLayoutEquipment();
....
@Transaction
@Query("") /* trick room into think it is doing something */
void /* or some useful return type */ doLotsOfThingsInASingleTransaction() {
.... if you want to do preparotory stuff
int deleteAllUserLocations_count = deleteAllUserLocations();
int deleteAllLineLayout_count = deleteAllLineLayoutEquipment();
.... etc
}
}
Then somewhere in you code you get an instance @Database
abstract class with the RoomDatabase built and then retrieve and then invoke the appropriate method (doLotsOfThinsInASingleTransaction
) after getting the respective @Dao
annotated interface/class instance via the abstract method in the @Database
annotated abstract class.
Here's an example (not run but compiled successfully)
A few @Entity
annotated classes (very basic as it's not about the complexity/design of tables):-
@Entity
class UserLocations {
@PrimaryKey Long id=null;
String user_name;
}
@Entity
class LineLayoutEquipment {
@PrimaryKey Long id=null;
String lle_name;
}
The @Dao
annotated abstract class (rather than the more typical interface (abstract class is more flexible due to methods with bodies)):-
@Dao
abstract class MyDoitAllStuffDao {
@Query("DELETE FROM userLocations")
abstract void deleteAllUserLocations();
@Query("DELETE FROM linelayoutequipment")
abstract void deleteAllLineLayoutEquipment();
@Transaction
@Query("")
void doLotsOfThingsInASingleTransaction() {
deleteAllUserLocations();
deleteAllLineLayoutEquipment();
}
}
@Database
annotated class, but makes more sense to include it before as the @Database
annotated class, when complete requires the @Dao
annotated class(es)The @Database
annotated abstract class (singleton):-
@Database(
entities = {UserLocations.class,LineLayoutEquipment.class},
exportSchema = false,
version = 1
)
abstract class TheDatabase extends RoomDatabase {
abstract MyDoitAllStuffDao getMyDoitAllStuffDao();
private static TheDatabase INSTANCE;
static TheDatabase getInstance(Context context) {
if (INSTANCE==null) {
return Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
.build();
}
return INSTANCE;
}
}
Finally using the above in activity code e.g. :-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
MyDoitAllStuffDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getMyDoitAllStuffDao();
dao.doLotsOfThingsInASingleTransaction();
}
}
So all you need to do is ensure you have instantiated the db and dao with scope for the Listener and use the last line (off the main thread though if following conventions).