I'm using a premade database and I seem to be getting an error when I try to update a row. The exact error from logcat is: (1) no such table: AUD. Heres what my dbhelper class looks like:
public class DataBaseHelper extends SQLiteOpenHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "/data/data/com.example.simplecurrency3/databases/";
private static String DB_NAME ="Currencies";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 2);// 1? its Database Version
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
this.mContext = context;
}
public void createDataBase() throws IOException {
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
And when I try to update a row:
Context context = getActivity().getApplicationContext();
DataBaseHelper dbHelper = new DataBaseHelper(context);
dbHelper.openDataBase();
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("UPDATE AUD SET AUD = 2.0")
You have never called createDataBase() method! You can put it into onCreate() method.
Good luck
Instead of updating a row, first check whether the table really exists by using the following query.
SELECT name FROM sqlite_master WHERE type='table'
Related
Sorry for the post but I didn't find something in the web. I use an existing database in my directory "assets". When I want to update a column the function returns that the column has changed, but in reality nothing happened. I tried with execSQL but nothing again.
Αny opinion will be appreciated!
Here is my DatabaseHelper code :
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "program.db";
public static String DBLOCATION = "";
public static final String TableName="ProgramTable";
private Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, 1);
this.mContext = context;
if(android.os.Build.VERSION.SDK_INT >= 17){
DBLOCATION = context.getApplicationInfo().dataDir + "/databases/";
}
else
{
DBLOCATION = "/data/data/" + context.getPackageName() + "/databases/";
}
}
#Override
public void onCreate(SQLiteDatabase db) {
}
private boolean checkDataBase()
{
File dbFile = new File(DBLOCATION + DBNAME);
return dbFile.exists();
}
//Copy the database from assets
public void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DBNAME);
String outFileName = DBLOCATION + DBNAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void openDatabase() {
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if (mDatabase != null && mDatabase.isOpen()) {
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void closeDatabase() {
if (mDatabase != null) {
mDatabase.close();
}
}
public long Like(int id) {
ContentValues contentValues = new ContentValues();
contentValues.put("Favourite",1);
mDatabase=this.getWritableDatabase();
openDatabase();
long k=mDatabase.update(TableName, contentValues, "ID =" +Integer.valueOf(id),null);
closeDatabase();
return k;
}
public long Unlike(int id) {
ContentValues contentValues = new ContentValues();
contentValues.put("Favourite",0);
mDatabase=this.getWritableDatabase();
openDatabase();
long k =mDatabase.update(TableName, contentValues, "ID ="+Integer.valueOf(id),null);
closeDatabase();
return k;
}
}
You need to open first your database before calling the getWritableDatabase();
try to swap your code.
from:
mDatabase=this.getWritableDatabase();
openDatabase();
to:
openDatabase();
mDatabase=this.getWritableDatabase();
Solution
I forgot to use the checkDatabase. In the constructor of DatabaseHelper must include:
if(!checkDataBase())
{
copyDataBase();
}
I'm extending DaoMaster.OpenHelper to manage assets folder database. Since it's not user related data the changes can be huge the only one thing I want to achieve is delete and recreate the database when there is a new version. What I don't understand is that this code works when i'm debugging my app on the emulator or even if i generate the apk and install it on my device manually. But when I deploy my app on the market and I install it on my device from there it looks like the it can't find the database.
Exception java.lang.RuntimeException: Unable to resume activity {com.livos.companionplants/com.livos.companionplants.main.MainActivity}: android.database.sqlite.SQLiteException: no such column: T.definition (code 1): , while compiling: SELECT T."_id",T."plant_id",T."definition" FROM "plant_definition" T ################################################################# Error Code : 1 (SQLITE_ERROR) Caused By : SQL(query) error or missing database. (no such column: T.definition (code 1): , while compiling: SELECT T."_id",T."plant_id",T."definition" FROM "plant_definition" T) #################################################################
#ApplicationScope
public class DatabaseOpenHelper extends DaoMaster.OpenHelper {
private String TAG = DatabaseOpenHelper.class.getSimpleName();
private static final String SP_KEY_DB_VER = "db_ver";
private static final int DATABASE_VERSION = 1;
private Context context;
private SharedPreferences sharedPreferences;
private SQLiteDatabase sqliteDatabase;
private static String DB_PATH;
private static String DB_NAME;
public DatabaseOpenHelper(Context context, SharedPreferences sharedPreferences, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
this.context = context;
this.sharedPreferences = sharedPreferences;
DB_NAME = name;
DB_PATH = context.getFilesDir().getAbsolutePath().replace("files", "databases") + File.separator;
try {
createDataBase();
} catch (Exception ioe) {
throw new Error("Unable to create database");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/** Open Database for Use */
public void openDatabase() {
String databasePath = DB_PATH + DB_NAME;
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
(SQLiteDatabase.OPEN_READWRITE));
}
/** Close Database after use */
#Override
public synchronized void close() {
if ((sqliteDatabase != null) && sqliteDatabase.isOpen()) {
sqliteDatabase.close();
}
super.close();
}
/** Get database instance for use */
public SQLiteDatabase getSqliteDatabase() {
return sqliteDatabase;
}
/** Create new database if not present */
public void createDataBase() {
SQLiteDatabase sqliteDatabase;
if (databaseExists()) {
int dbVersion = sharedPreferences.getInt(SP_KEY_DB_VER, 1);
// If different version then delete current database and copy the new one from assets
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DB_NAME);
boolean dbFileDeleted = dbFile.delete();
if (!dbFileDeleted) {
Log.w(TAG, "Unable to update database");
} else {
createDataBase();
}
}
/* Check for Upgrade */
} else {
/* Database does not exists create blank database */
sqliteDatabase = this.getReadableDatabase();
sqliteDatabase.close();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.apply();
copyDataBase();
}
}
/** Check Database if it exists */
private boolean databaseExists() {
SQLiteDatabase sqliteDatabase = null;
try {
String databasePath = DB_PATH + DB_NAME;
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
return sqliteDatabase != null;
}
/**
* Copy existing database file in system
*/
public void copyDataBase() {
int length;
byte[] buffer = new byte[1024];
String databasePath = DB_PATH + DB_NAME;
try {
InputStream databaseInputFile = this.context.getAssets().open(DB_NAME);
OutputStream databaseOutputFile = new FileOutputStream(databasePath);
while ((length = databaseInputFile.read(buffer)) > 0) {
databaseOutputFile.write(buffer, 0, length);
databaseOutputFile.flush();
}
databaseInputFile.close();
databaseOutputFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean isRoboUnitTest() {
return "robolectric".equals(Build.FINGERPRINT);
}
Solution using Kuffs proposition
#ApplicationScope
public class DatabaseOpenHelper extends DaoMaster.OpenHelper {
private String TAG = DatabaseOpenHelper.class.getSimpleName();
private static final String SP_KEY_DB_VER = "db_ver";
private static final int DATABASE_VERSION = 2;
private Context context;
private SharedPreferences sharedPreferences;
private SQLiteDatabase sqliteDatabase;
private static String DB_PATH;
private static String DB_NAME;
public DatabaseOpenHelper(Context context, SharedPreferences sharedPreferences, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
this.context = context;
this.sharedPreferences = sharedPreferences;
DB_NAME = name;
try {
createDataBase();
} catch (Exception ioe) {
throw new Error("Unable to create database");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/** Open Database for Use */
public void openDatabase() {
String databasePath = context.getDatabasePath(DB_NAME).toString();
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
(SQLiteDatabase.OPEN_READWRITE));
}
/** Close Database after use */
#Override
public synchronized void close() {
if ((sqliteDatabase != null) && sqliteDatabase.isOpen()) {
sqliteDatabase.close();
}
super.close();
}
/** Get database instance for use */
public SQLiteDatabase getSqliteDatabase() {
return sqliteDatabase;
}
/** Create new database if not present */
public void createDataBase() {
SQLiteDatabase sqliteDatabase;
if (databaseExists()) {
int dbVersion = sharedPreferences.getInt(SP_KEY_DB_VER, 1);
/* If different version then delete current database and copy the new one from assets*/
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DB_NAME);
boolean dbFileDeleted = dbFile.delete();
if (!dbFileDeleted) {
Log.w(TAG, "Unable to update database");
} else {
createDataBase();
}
}
} else {
/* Database does not exists create blank database */
sqliteDatabase = this.getReadableDatabase();
sqliteDatabase.close();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.apply();
copyDataBase();
}
}
/** Check Database if it exists */
private boolean databaseExists() {
SQLiteDatabase sqliteDatabase = null;
try {
String databasePath = context.getDatabasePath(DB_NAME).toString();
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
return sqliteDatabase != null;
}
/**
* Copy existing database file in system
*/
public void copyDataBase() {
int length;
byte[] buffer = new byte[1024];
String databasePath = context.getDatabasePath(DB_NAME).toString();
try {
InputStream databaseInputFile = this.context.getAssets().open(DB_NAME);
OutputStream databaseOutputFile = new FileOutputStream(databasePath);
while ((length = databaseInputFile.read(buffer)) > 0) {
databaseOutputFile.write(buffer, 0, length);
databaseOutputFile.flush();
}
databaseInputFile.close();
databaseOutputFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
yoh...
I was trying to retrieve data from my external database in assets
but when I run the app, seems like it created another database in /data/data/packagename/databases/ :-( not the external database from assets I inserted and causing an error(Unfortunately, App has stopped). Here's my Code:
ingameinterface .java*
public class ingameinterface extends Activity {
DBHelper dbhelper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ingameinterface);
String[] from = new String[] { "CtrlNo", "Prima", "Key_Word", "Val" };
int[] to = new int[] { R.id.itmCc1, R.id.itmCc2, R.id.itemCc3, R.id.itemCc4};
dbhelper = new DBHelper(this);
try {
dbhelper.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Cursor c = dbhelper.getData();
if (c.getCount() == 0) {
showmessage("Error!", "Nothing found.");
return;
}
StringBuffer buff = new StringBuffer();
while (c.moveToNext()) {
buff.append("Controlnum: " + c.getString(0) + "\n");
buff.append("Prima: " + c.getString(1) + "\n");
buff.append("Word: " + c.getString(2) + "\n");
buff.append("Value: " + c.getString(3) + "\n\n");
}
showmessage("Data", buff.toString());
}
public void showmessage(String title, String Message){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(Message);
}
}
and
DBHelper.Java*
public class DBHelper extends SQLiteOpenHelper {
private static String DB_NAME = "db_vocabulary";
private SQLiteDatabase db;
private final Context context;
private String DB_PATH;
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
this.context = context;
DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/";
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
// throw new Error("Error copying database");
}
}
}
private boolean checkDataBase() {
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
private void copyDataBase() throws IOException {
InputStream myInput = context.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public Cursor getData() {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
Cursor c = db.rawQuery("SELECT * FROM TblWords WHERE Prima = 1", null);
return c;
}
#Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
use this in your DBHelper.java file:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists "+TABLE_NAME+"(PHONENUMBER VARCHAR,NAME VARCHAR)");
}
so that it will wont create another table if already that table exits in database.
This question already has answers here:
Copy Database from assets folder in unrooted device
(6 answers)
copy database from assets to databases folder [duplicate]
(1 answer)
Closed 9 years ago.
I want to copy my sample database from my asset folder to the /data/data/packagename/databases/ directory to use it later in the application.
I have viewed many tutorial and other solution like here( Copy Database from assets folder in unrooted device) and here (copy database from assets to databases folder) but it not work for me. I have no error but the database that has been copied is empty. Is there something wrong with my coding?
Here is my coding for copying the database.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_dictionary_type);
File dbfile=new File("data/data/com.example.myidictionary/databases","DefinitionDB");
if (!dbfile.exists()) {
try {
copyDatabase(dbfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Sample data is being copied", Toast.LENGTH_LONG).show();
}
else
Toast.makeText(getApplicationContext(), "Database Exist", Toast.LENGTH_LONG).show();
}
private void copyDatabase(File dbFile) throws IOException
{
InputStream is = this.getAssets().open("DefinitionDB");
OutputStream os = new FileOutputStream(dbFile);
byte[] buffer = new byte[1024];
while (is.read(buffer) > 0)
{
os.write(buffer);
}
os.flush();
os.close();
is.close();
}
Try below code and let me know whether is it working properly?
public class DataBaseWrapper extends SQLiteOpenHelper
{
private static String TAG = DataBaseWrapper.class.getName();
private String DB_PATH; //= "/data/data/com.example.yourproject/databases/";
private static String DB_NAME = "Database.sqlite";
private SQLiteDatabase myDataBase = null;
private final Context myContext;
public DataBaseWrapper(Context context)
{
super(context, DB_NAME, null, 1);
this.myContext = context;
DB_PATH="/data/data/" + context.getPackageName() + "/" + "databases/";
Log.v("log_tag", "DBPath: " + DB_PATH);
// File f=getDatabasePath(DB_NAME);
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
Log.v("log_tag", "database does exist");
}else{
Log.v("log_tag", "database does not exist");
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
private void copyDataBase() throws IOException{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
private boolean checkDataBase(){
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
myDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase != null;
}
#Override
public synchronized void close()
{
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db)
{
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.v(TAG, "Upgrading database, this will drop database and recreate.");
}
}
I have an app already in google store.I am using a builtin database having 3 tables and copying it on first launch of app. Now i want to do upgrade to the app and add another table. Below is my code.
public DataBaseHelper(Context context)
{
super(context, DB_NAME, null, 1);
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
this.mContext = context;
}
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}
//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
String sql = "CREATE TABLE IF NOT EXISTS CKRecordings (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT , filepath TEXT , creationDate TEXT)";
db.execSQL(sql);
db.execSQL("DROP TABLE IF EXISTS data");
onCreate(db);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
I want to ask few questions. The above code is not upgrading.
Now if i am new user of the app, do i have to edit the old database and make another CKRecording table and replacing it with current database placed in asset or above code will work for new users too?
super(context, DB_NAME, null, 1);
in this statement last argument is database version.. set it to 2 for new updated APK. so existing user can have newly added table Or Column.
on updated apk onUpgrade will call. and there you can copy database from asset. but than exisiting user will have loss of data.. so best option is to add table dynamically in database.