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...
Related
I am new to Xamarin and android development. I am making a timetable app and currently have no idea of how to create a database using sqlite.net. Is there possibly any documentation of all the commands that can be used and a thorough description somewhere? Because all i could find are stuffs related to Java, IOS, and other stuffs.
In my app, i need to create, access, insert, modify and draw links between database, I am unsure of how to do any.
thanks
Using SQLite.nET is very easy in Xamarin Android/iOS/Forms. Simply add a nuget package "sqlite-net" intp your project. This will add two files, SQLIte.cs and SQliteAsync.cs in your root folder. It uses ORM hance its CRUD functions can be used easily.
Here are few links from Xamarin that will help you understand the concepts better.
https://developer.xamarin.com/guides/cross-platform/application_fundamentals/data/part_3_using_sqlite_orm/
https://developer.xamarin.com/recipes/android/data/databases/sqlite/
https://developer.xamarin.com/recipes/ios/data/sqlite/
https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/
https://developer.xamarin.com/recipes/ios/data/sqlite/create_a_database_with_sqlitenet/
EDIT 1:
Include sqlite-net nuget package by Frank Krueger in your application.
Create a file for keeping all Databse related functions. For instance DbOperations.cs
public class DbOperations
{
public string SqLiteDBPath { get; private set; }
public DbOperations()
{
string databasePath = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Personal), DBConstants.DATABASE_PATH);
_sqLiteDBFilePath = System.IO.Path.Combine(databasePath, DBConstants.DATABASE_NAME);
SqLiteDBPath = databasePath;
System.IO.Directory.CreateDirectory(SqLiteDBPath);
//create database in set path
SQLite.SQLite3.Config(SQLite.SQLite3.ConfigOption.Serialized);
SQLiteConnection sqLiteConnection = new SQLiteConnection(_sqLiteDBFilePath);
sqLiteConnection.Close();
CreateTables();
}
private void CreateTables()
{
SQLiteConnection sqLiteConnection = new SQLiteConnection(_sqLiteDBFilePath);
sqLiteConnection.CreateTable<User>();
sqLiteConnection.Close();
}
}
This snippet will create database and table for object named User in the db.
To perform CRUD operations simply write
SQLiteConnection con = new SQLiteConnection(_sqLiteDBFilePath);
con.Insert(userObject); //Insert
con.Delete(userObject); //Delete
con.DeleteAll<>(); //Delete All rows in table User
con.Update(userObject); //Update
List<User> userList = con.Query<User>("select * from User"); //Select all
Hope this helps you.
I need to delete all the databases stored in the database space of the application. I stored them using this path: context.getDatabasePath("db1").getAbsolutePath()
I have a lot of databases, with random names, so i dont know al the names, i just want to delete all of them.
I tryed with this:
String filesDir = ApplicationContextProvider.getContext().getFilesDir().getAbsolutePath();
File cache = new File(filesDir);
if (cache.isDirectory()) {
String[] children = cache.list();
for (int i = 0; i < children.length; i++) {
System.out.println("Deleting: "+children[i]);
new File(cache, children[i]).delete();
}
}
But it doesn't works. The databases are still there.
You don't need to know that path. Just use the list of databases you can get to delete them.
for (String databaseName : context.databaseList()) {
context.deleteDatabase(databaseName);
}
If you really need it
File databasesPath = context.getDatabasePath("ignored").getParentFile();
The path you get via getFilesDir is a different one.
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.
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());
}
}
I created a database in Android using below line of code-
SQLiteDatabase sampleDB = this.openOrCreateDatabase("SAMPLE_DB_NAME",
MODE_PRIVATE, null);
Now, i want to know what would be the Uri for this database or how to find the Uri of the created database.Please help me out.
Thanks in Advance
Manoj
content://com.package_name.dbprovider_name/table_name
you have implement following code
File dbFile = this.getDatabasePath(DB_NAME);
for (File f:files)
{
if (f.isDirector)
searchFile(f);
else if (f.getName().equals("accounts.db"))
{
// delete db here...
// and exit the search here...
}
}
if it contains the accounds.db. If you reach another subdirectory, call your own function recursively with the subfolder as the starting point,