How to execute the query in a plain text file in Android? - android

I can read a text file which is in the assets folder. But now I have a DB creation query in the text file; how can I execute that query in Android? Please don't ask why I want to keep queries in a plain text file.

You should use a SqliteOpenHelper and override the onCreate method.
Inside that method you should read the file from resources and execute it.
See this for how to use an SqliteOpenHelper
Then for reading file from resources just do this (from here):
#Override
public void onCreate(SQLiteDatabase database) {
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.sql);
byte[] b = new byte[in_s.available()];
in_s.read(b);
String sql = new String(b);
database.execSQL(sql);
}
Then you also need to implement onUpgrade (since it is marked as abstract) but you don't need to do anything in that method until you decide to change the structure of your database.

Related

Android studio conection with SQL table DB browser

Straight to point:
I am making a Quizz app in Android studio. I would like to get the question (and answers) that will fill the app from SQL table that i made in DB browser for SQLite.
My question is how do i connect those two (without rettyping all those question in android studio).
I have in somethin like a structure {ID, qusetion, answer} and I only point ID number i whant to fetch from the table and it fills my array in android studio.
I hope this make sense :)
Regards
You could put every question and answer in a file, line by line, things separated by a specific character.
ex:
What's the color of the sky?;Blue;Red;Yello;Black
Who is Harry potter?;A magician;A girl;A burrito;A car
And read the file, and insert everything them in the database on the first time you open the app.
Assuming you're able to export from DB Browser to a .sql file (including CREATE TABLE statements as you'll effectively be creating a new database from scratch), you can use this exported file to recreate your database in your app.
By overriding the SQLiteOpenHelper.onCreate() method, you could do something like this:
#Override
public void onCreate(SQLiteDatabase db) {
// Open the raw SQL file
InputStream inputStream = context.getResources().openRawResource(R.raw.mydb);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
// Read the file
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
// Pump the statements into the database
String queries = sb.toString()
for (String query : queries.split(";")) {
db.execSQL(query);
}
}
Replacing mydb with whatever the name of your sql file is in /res/raw

How to properly delete a database with Couchbase Lite Android?

I know that a Database object has a delete() method to delete a database.
But in the case where the database is corrupted (for instance), the opening of the database fails and consequently we don't have this Database object, which allows us to delete it (and then create a new empty one).
So, how is it possible to delete the database file if it is not possible to open this database?
I know that I could delete it manually doing something like:
Context context = ...;
String databaseName = ...;
Manager manager = new Manager(new AndroidContext(context), Manager.DEFAULT_OPTIONS);
File databaseDirectory = manager.getDirectory();
if (databaseDirectory != null) {
File databaseFile = new File(databaseDirectory, databaseName + ".cblite2"); // Or ".cblite"...
if (databaseFile.exists()) {
FileDirUtils.deleteRecursive(databaseFile);
}
}
But the fact I have to know the extension of the file is ugly for me...

Lots of inserts into SQLite database from CSV file

When the user downloads my app for the first time, the app downloads a CSV file which contains about 100,000 rows of data.
Then, I would like to populate my SQLite database with it.
Here is my code:
InputStream inputStream = activity.openFileInput(file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
dbHelper.beginTransaction();
while((line = bufferedReader.readLine()) != null) {
String[] values = line.replaceAll("'", "''").split(",");
dbHelper.insert(values);
}
dbHelper.setTransactionSuccessful();
dbHelper.endTransaction();
dbHelper.close();
In my DBHelper class, here is the method insert:
public void insert(String[] data) {
ContentValues values = new ContentValues();
values.put(DBHelper.SHAPE_ID, data[0]);
values.put(DBHelper.SHAPE_PT_LAT, data[1]);
values.put(DBHelper.SHAPE_PT_LON, data[2]);
values.put(DBHelper.SHAPE_PT_SEQUENCE, data[3]);
myDB.insert(DBHelper.TABLE_SHAPES, null, values);
}
I tried this code, it worked BUT it took 7 minutes to do it...
Am I doing something wrong ? Is there a better way (read faster) to populate a SQLite database?
You should download the SQLite database file itself.
If there is other data in the database that you want to keep, you could either
copy that other data into the downloaded database (since it is not as much data, this should be fast); or
keep the downloaded database and the other database separated (and ATTACH one to the other if you need to do joins between them).
Use a prepared statement, that should give a performance boost.
Something like:
SQLiteStatement statement = db.compileStatement("INSERT INTO " + TABLE_SHAPES + " VALUES(?, ?));
and change your insert() method to do something like:
statement.bindString(1, data[0]);
statement.bindString(2, data[1]);
statement.executeInsert();
According to this, SQLite3 has facilities to import a CSV file built-in:
.separator ','
.import '/path/to/csv/data' [table]
I'd imagine this can be done on Android using the DatabaseUtils.InsertHelper:
DatabaseUtils.InsertHelper helper = new DatabaseUtils.InsertHelper(dbFilePath, dbTablename);
helper.prepareForInsert();
// use the bind* methods to bind your columns of CSV data to the helper in a loop
helper.execute();
I also see the the class is now marked as deprecated (API level 17) in lieu of SQLiteStatement, which may or may not be relevant to your application. If you have further questions, please leave a comment.

SQLite database created on Android and edited with Firefox SQlite manager

I initially created an SQLite database on Windows and then had problems accessing it within Android.
Subsequently I created a database on Android and then copied it out. At this point it only had the android_metadata table in it.
I then imported some data via CSV and added it back into my project. The DbHelper class in my project copies the database into /data/data/my.project/databases/.
Now, when I run a raw query from this database, if I try to access the table imported by CSV, I get an error saying that the table doesn't exist. If I try to access the android_metadata table which I created on Android then there is no error.
The database in my assets definitely has the table in that I wish to copy over to the /data/data/example.project/databases folder and the copy routine is definitely called - I've checked with the log output.
Now, if I comment out the copy code, a database is automatically created which contains the android_metadata table in there and it is ~3 KB.
When the copy code is live the database is created as ~8 KB. This is the size of the database in the assets, so it appears that it has been successfully copied. However, when I pull that database back to my desktop from DDMS it is ~8 KB, but it doesn't contain the table which is in the one in the assets folder. If I manually copy directly from desktop into /data/data... then the database works (but this will not be possible with a market app).
Here is my copy code for copying the database:
public void createDatabase() throws IOException {
Log.i(TAG, "createDatabase called");
InputStream assetsDB = mContext.getAssets().open(DATABASE_NAME);
OutputStream dbOut = new FileOutputStream(DATABASE_PATH);
Log.i(TAG, DATABASE_PATH);
Log.i(TAG, assetsDB.toString());
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer))>0) {
Log.i(TAG, "WritingDB block" + length);
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
}
How can I fix this problem?
I've rectified this using another example which doesn't override onCreate with the database copy code and handles the copying of the database on its own. I don't really understand why it doesn't work when calling the onCreate method.
Have you seen Using your own SQLite database in Android applications?
This page is a good source for the topic. But, there is a little problem. Actually, it is not a problem and explained how to fix in the page. Look at comments.
If your database is sort of largish or smallish (> 1 MB, < 100 KB (I am not sure about these values)). It seems that it is compressed and that causes confusion in the Android read on the InputStream. The trick is to rename your asset to a file that the packager will not try to compress. Renaming the database file from xxx to xxx.mp3 or xxx.txt or something like that does the trick.
If I clearly understand you, I had the same problem with loading an SQLite database from other sources (I used to the Firefox SQLite manger too).
I want to read a temporary database from the assets folder at startup and fill my application database with test data, and I usually get this error.
I need to put this code before loading my test database:
final SQLiteDatabase db = getReadableDatabase();
db.close();
My database helper class:
public DataBaseHelper(Context context) {
super(context,
DataBaseHelper.DATABASE_NAME,
null,
DataBaseHelper.DATABASE_VERSION);
this.context = context;
// Temporary copy test database
loadMockDataBase();
dataBase = getWritableDatabase();
}
#Override
public final synchronized void close() {
if (dataBase != null) {
dataBase.close();
}
super.close();
}
private void loadMockDataBase() {
final SQLiteDatabase db = getReadableDatabase();
db.close();
try {
copyDataBase();
}
catch (final IOException e) {
Log.d(SystemConfiguration.LOG_TAG, e.getMessage());
}
}

How to access one class database in another class?

I created a database in my class like
public final String CRAZY_ALARM_DB_NAME = "CrazyDb";
public final String CRAZY_ALARM_TABLE_NAME = "CrazyTable";
alarmDB = this.openOrCreateDatabase(
CRAZY_ALARM_DB_NAME, MODE_PRIVATE, null
);
alarmDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ CRAZY_ALARM_TABLE_NAME
+" (REQ_CODE INT(3),DAY INT(3),HOUR INT(3)"
+",MINUTE INT(3),COUNT INT(3),REPEAT INT(3)"
+",DAYS VARCHAR2(100),SUN INT(3),MON INT(3),"
+"TUE INT(3),WED INT(3),THU INT(3),FRI INT(3),"
+"SAT INT(3));"
);
cr = alarmDB.rawQuery("SELECT * FROM "
+CRAZY_ALARM_TABLE_NAME, null
);
so i want to use this database in another class. I am also do the same thing ,i wrote "openorcreate "code in another class and also cursor..
but it gave an exception like no such table while compiling ... at cursor line..
please help me.
You should use an SQLiteOpenHelper-class to access and maintain your Database.
If you do so, you can (in whatever class you like) use the following lines to get a read or writable database:
YourSQliteOpenHelper db_con = new YourSQliteOpenHelper(getApplicationContext());
// Readable:
SQLiteDatabase db = db_con.getReadableDatabase();
// Writeable:
SQLiteDatabase db = db_con.getWritableDatabase();
A tutorial on how to use the SQLiteOpenHelper can be found here.
The best you could do is to have a database helper where you could have all these calls and which could be available and accessible by all your activities.
Moreover, you should remove and install again your app in order to be able to create the table. I have this problem sometimes.

Categories

Resources