I am developing an ionic app, and it have several native parts
I am using this plugin, for local databases
https://github.com/litehelpers/Cordova-sqlite-storage
I have no problem in creating or accessing it from the hybrid part, with functions like this:
var db = window.sqlitePlugin.openDatabase({
name: "dbApplication.sqlite",
path: 'documents/',
environment: "SQLITE_ENV_MOBILE",
bgType: 1
});
db.transaction(function (tx) {
tx.executeSql("INSERT INTO main.table ( name, email, sfid ) VALUES (?,?,?)", [user.name, user.email, user.sfid], function () {
deferred.resolve();
}, errorCallback);
}, errorCallback);
But i am trying to access it from the android native part, with this code:
private static String DB_PATH = "documents/";
private static String DB_NAME ="dbApplication.sqlite";// Database name
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
return mDataBase != null;
}
public HashMap getDataSigner(Integer signerId) {
openDataBase();
SQLiteDatabase db = mDataBase;
//"CREATE TABLE IF NOT EXISTS main.signers (idSigner INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT, idNumber TEXT, rol TEXT)"
Cursor c=db.rawQuery("SELECT name, idNumber FROM signers WHERE idSigner="+signerId+"", null);
HashMap signer = new HashMap();
if(c.moveToFirst())
{
signer.put("name", c.getString(0));
signer.put("idNumber", c.getString(1));
}
return signer;
}
It returns the following error:
Failed to open database 'documents/dbApplication.sqlite'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error(Sqlite code 14): Could not open database,(OS error - 2:No such file or directory)
So my question is: What is the correct path to the databases, in android, for the databases created with the sqlite plugin?
I have also try to dig in the plugin code, but I dont understand it well, as I am not a good android programmer
Also, if someone have the way to access it from IOS native, it would be awesome, as I am going to need it later
Thanks!
I answer to myself
The correct Path, in Android is:
mDataBase = SQLiteDatabase.openDatabase(this.cordova.getActivity().getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.CREATE_IF_NECESSARY);
Also, remember to close conections before use, if not, you couldn't use it
Related
I am using DBFlow with SQLCipher. I am trying to encrypt the already existing SQLite Database(using DBFlow) with SQLCipher in Android.
I used the following code to encrypt the DB:
private void encryptDB() {
SQLiteDatabase.loadLibs(this);
String password = "test123";
String LEGACY_DATABASE_NAME = "legacy.db";
String NEW_DATABASE_NAME = "new_crypt.db";
File newDBFile = getDatabasePath(NEW_DATABASE_NAME);
File legacyFile = getDatabasePath(LEGACY_DATABASE_NAME);
if (!newDBFile.exists() && legacyFile.exists()) {
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(legacyFile, "", null);
db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", newDBFile.getAbsolutePath(), password));
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");
db.close();
db = SQLiteDatabase.openDatabase(newDBFile.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE);
db.close();
legacyFile.delete();
newDBFile.renameTo(legacyFile);
}
}
The DB is encrypted fine but when I am trying to write any operations:
Place place = new Place();
place.setName("Test");
place.save();
DB Model:
#Table(database = DatabaseManager.class)
public class Place extends BaseModel {
#Column
String name;
// set and get methods goes here
}
then getting the following exception:
io.reactivex.exceptions.UndeliverableException: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032 SQLITE_READONLY_DBMOVED[1032])
I found a similar post here but not found any solution to it.
Also, I found this to encrypt the DBFlow database with SQLCipher and implemented it. Then it is working if I install it as a fresh app but when I install this app on top of the old app which is having not encrypted DB then it is failing.
net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
Please suggest how can I fix this?
This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 4 years ago.
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
Here is my code for sqlite in android studio
public class Database extends SQLiteAssetHelper{
private static final String DB_NAME="Jerson.db";
private static final int DB_VER=1;
public Database(Context context)
{
super(context, DB_NAME,null,DB_VER);
}
public List<Orders> getCarts()
{
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String[] sqlSelect={"MenuId","Name","Quantity","Price"};
String sqlTable="OrderDetails";
qb.setTables(sqlTable);
Cursor c = qb.query(db,sqlSelect,null,null,null,null,null);
final List<Orders> result = new ArrayList<>();
if (c.moveToFirst())
{
do {
result.add(new Orders(c.getString(c.getColumnIndex("MenuId")),
c.getString(c.getColumnIndex("Name")),
c.getString(c.getColumnIndex("Quantity")),
c.getInt(c.getColumnIndex("Price"))
));
}while (c.moveToNext());
}
return result;
}
public void addToCart(Order order)
{
SQLiteDatabase db = getReadableDatabase();
String query = String.format("INSERT INTO OrderDetails(MenuId,Name,Quantity,Price)VALUES('%s','%s','%s','%s');",
order.getMenuId(),
order.getName(),
order.getQuantity(),
order.getPrice());
db.execSQL(query);
}
public void cleanCart()
{
SQLiteDatabase db = getReadableDatabase();
String query = String.format("DELETE FROM OrderDetails");
db.execSQL(query);
}
}
I am sure I have a table in sqlite I dont know why its returning me no such table
here is a snippet of code on where I use the database
btnCart.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
new Database(getBaseContext()).addToCart(new Order(
foodId,
currentFood.getName(),
numberButton.getNumber(),
currentFood.getPrice()
));
Toast.makeText(FoodDetail.this, "Added To Cart", Toast.LENGTH_SHORT).show();
}
});
The most common cause for table not found is that it hasn't been created when the database is created. This may be due to an SQL error in the tale create statement or issues encountered when copying a packaged database from the assets folder.
The latter can be a badly written copy process, hence why SQLiteAssetHelper is frequently recommended as it's tried and tested. However, even with SQliteAssetHelper a bad file can result in such an error, such a database saved before the table is created as some SQLite Tools can allow.
When using SQLiteAssethelper, as per this question. The fix should be to :-
Delete the App's Data or Uninstall the App (both will delete the existing database allow it be copied (SQLiteAssethelper checks to see if the Database exists, if so then it doesn't attempt to copy the asset)).
Check that Database is sound using an SQlite tool and save it.
Copy the saved file (best done outside of Android Studio) to the App's assets/database folder (creating the assets folder and databases folder if need be).
Rerun the App.
the table ( i.e. vaccines) structure is :
id- auto increment primary key
dose1_date - string
dose2_date - string
The DatabaseAccessor class is as follows. The initDB() and setVaccineDates methods are called from another activity. But the database is not updated. The logged message is found in the logcat however. The DatabaseHelper class is not shown here.
public class DatabaseAccessor {
public static DataBaseHelper myDbHelper = null;
public static SQLiteDatabase rdb = null;
public static SQLiteDatabase wdb = null;
public static synchronized final void initDB(Context context) throws Exception {
if (myDbHelper == null) {
myDbHelper = new DataBaseHelper(context);
myDbHelper.openDataBase();
rdb = myDbHelper.getReadableDatabase();
wdb = myDbHelper.getWritableDatabase();
}
}
public static void setVaccineDates(String birthDate) throws SQLException{
try {
String[] selections = null;
String qry = null;
qry = "select * from vaccines order by id";
Cursor cursor = wdb.rawQuery(qry, selections);
Log.d("update qry===== ", qry);
while (cursor.moveToNext()) {
int rowID = Integer.parseInt(cursor.getString(0));
ContentValues values = new ContentValues();
values.put("dose1_date","66666");
values.put("dose2_date","7777");
wdb.update("vaccines", values, "id=?", new String[] {String.valueOf(rowID)});
//wdb.close();
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
}// end of method setVaccineDates
}
What to do ?
Edit : If I uncomment the wdb.close() line , I see in logcat
'06-09 04:21:05.387: W/System.err(4144): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.cloudsoft.vaccine/databases/vaccines2.db
'
As a newbie in android it was just a mistake out of ignorance that this situation took place: after update operation I tried to find the changes in the database file (i.e. file with .db extension sitting inside assets folder in Eclipse) through sqlite browser . But what actually happens is the app running in the device (real one or emulator) has its own database which is created from the .db extension file inside assets folder and consequent database operations only affect the app's own database leaving no touch on the database inside the mentioned folder in Eclipse. And there is the way to watch the app's very own database in the running device in Eclipse's 'File Explorer' (in DDMS mode) with the help of Questoid SQlite Manager
I am so new and new in android , i have a big problem with it, i create an app that needs to connect to database .so i create a database using sqllite expert pro as you can see here :
CREATE TABLE [user](
[name] tEXT,
[id] INT PRIMARY KEY);
My database name is a .i want to read the value from the user table as you can see here in my code :
SQLiteDatabase mydatabase = openOrCreateDatabase("a",MODE_PRIVATE,null);
Cursor resultSet = mydatabase.rawQuery("Select * from user",null);
resultSet.moveToFirst();
String username = resultSet.getString(1);
String password = resultSet.getString(2);
TextView tv = (TextView) findViewById(R.id.editText1);
tv.setText("Text is: " + username + password);
but it doesn't work ,should i add connection string to my code ,or should i import the database into my project,because the database is in my workspace folder.
I use this code to create a test database inside android ,but it doesn't work again?
SQLiteDatabase mydatabase = openOrCreateDatabase("ali",MODE_PRIVATE,null);
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS TutorialsPoint(Username VARCHAR,Password VARCHAR);");
mydatabase.execSQL("INSERT INTO TutorialsPoint VALUES('admin','admin');");
Cursor resultSet = mydatabase.rawQuery("Select * from TutorialsPoint",null);
resultSet.moveToFirst();
String username = resultSet.getString(1);
String password = resultSet.getString(2);
Your database needs to be copied to the phone's internal storage first. You can do it manually or with the help of this library Android SqliteAsset Helper
Follow the right method for creating database in android using codes:
Create a class that extends SqliteOpenHelper.
public class DbOpener extends SqliteOpenHelper {
DbOpener(Context c){
super(c, 1, "a", null, 1); //where "a" is the database name
}
public void onCreate (SqliteDatabase db){
db.execSQL("CREATE TABLE TutorialsPoint (Username VARCHAR, Password VARCHAR);");
}
}
Then in your activity use it as follows:
DbOpener opener = new DbOpener(this);
SqliteDatabase myDatabase = opener.getWritableDatabase();
//Now you can perform all your queries (including insertions) using the myDatabase object
First, you should change your database name to a readable one like "mydata.db"
Second, there is no need for connection string on using SQLite in Android like the usual ways we do with accessing database from Java code.
You need to access database by using SQLiteOpenHelper. Tutorial from Android SQLite database and content provider. Try to get the feel with Android and SQLite from the tutorial.
Then, after you've mastering the concept and know the how, you can use your predefined database by utilizing Android SQLiteAssetHelper
I have a normal opening of a database file, it works perfectly fine when opening a blank db file with only the metadata table, but as soon as I make another table, it causes the app to crash. Maybe it's different version db files? Please comment if you need more of the code
private static String DB_PATH = "/data/data/com.example.andrew.ubair4/databases/";
private static String DB_NAME = "coordinates";
String myPath = DB_PATH + DB_NAME;
private SQLiteDatabase db;
public DataBaseHelper(Context context){
super(context, DB_NAME, null, 1);
this.myContext = context;
Log.d("TAGG","enter constructor");
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); //<---- crashes right here IF I have a second table in the database
Log.d("TAGG","2");
My metadata table:
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')
INSERT INTO "android_metadata" VALUES ('en_US')
Add 1 more table:
CREATE TABLE something (
column1,
column2,
column3,
PRIMARY KEY (column1)
);
Edit: Okay, I have new information. If I so much as take the db file, email it to myself, and replace it back into the original directory. It'll crash. Yes you heard me. I don't even alter the file, I just email the file to myself, delete the original, and replace it with the exact same file. Then it crashes. I'm about to tear my hair out.
As I can see, you are opening the DB in read-only mode. Adding the table - is a modification, and exception thrown shows you that you should open it in write mode before modifying it scheme or adding\deleting some data.