Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate Room database using csv file

I have 9000 cities that i need to save on database to allow the users to search by cities.

My Room table is:

@Entity
public class City extends Model{

    @PrimaryKey
    @NonNull
    private String id = UUID.randomUUID().toString();

    private String name;
    private String state;

    public City(@NonNull String id, String name, String state) {
        this.id = id;
        this.name = name;
        this.state = state;
    }

    @Ignore
    public City() {
    }

    @Ignore
    public City(String name, String state) {
        this.name = name;
        this.state = state;
    }

    @NonNull
    public String getId() {
        return id;
    }

    public void setId(@NonNull String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return name + " - " + state;
    }
}

My DAO is

@Dao
public interface CityDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(List<City> cities);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(City city);

    @Update
    void update(City city);

    @Delete
    void delete(City city);

    @Query("DELETE FROM City WHERE id = :id")
    void delete(String id);

    @Query("SELECT * FROM City")
    List<City> getAll();

    @Query("SELECT * FROM City WHERE id = :id LIMIT 1")
    City findById(String id);

    @Query("DELETE FROM City")
    void removeAll();
}

The .csv file contains rows like

1;AC;Acrelandia
2;AC;Assis Brasil

where the rows are: ID, state and name.

And my DatabaseModule is the next:

@Module
public class DatabaseModule {
    @Singleton
    @Provides
    SontraDB provideDb(Application app) {
        return Room.databaseBuilder(app, MyDB.class, "mydb.db")
                .build();
    }

      @Singleton
        @Provides
        CityDao provideCityDao(MyDB db) {
            return db.cityDao();
        }

I found that we can set an "addCallback" option to the database builder, to setup data when the DB is initialized.. but, how can i access the dao there?

return Room.databaseBuilder(context,
                MyDB.class,
                "mydb.db")
                .addCallback(new Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        super.onCreate(db);
                        Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                // insert data using DAO
                            }
                        });
                    }
                })
                .build();

Any ideas how to do this?

Any help would be greatly appreciated!

like image 334
mapo Avatar asked Jul 31 '18 21:07

mapo


1 Answers

I had to do something similar with JSON recently and you're pretty close to solving your problem. I would create a static helper class to read the CSV files into a List of City objects, let's say that method has a signature like public List<City> getCityList() in a CsvUtils class. Then in your .addCallBack you would do something like:

@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
    super.onCreate(db);
    Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
        @Override
        public void run() {
            // insert data using DAO
            provideCityDao(db).insertAll(CsvUtils.getCityList());
        }
    });
}
like image 51
Maya McKela Avatar answered Oct 18 '22 23:10

Maya McKela