My dictionary app project uses SQLite for storing data. I'm getting UNIQUE constraint failed: type.ps in the methodcreateTablesAndProcess() when I run the app.
createTablesAndPorcess method:
public final void createTablesAndProcess() {
boolean z = true;
try {
if (!doesExistsTable("other_words")) {
this.wdb.execSQL("create table if not exists other_words(word TEXT PRIMARY KEY)");
this.wdb.execSQL("INSERT INTO other_words ( word ) SELECT DISTINCT w FROM ( SELECT ot AS w FROM oten UNION SELECT word AS w FROM other )");
}
} catch (Exception e) {
try {
e.printStackTrace();
z = false;
} catch (Exception e2) {
e2.printStackTrace();
return;
}
}
try {
if (!doesExistsTable("new_study_plan")) {
this.wdb.execSQL("create table if not exists new_study_plan(serial INTEGER PRIMARY KEY , word TEXT , add_time INTEGER NOT NULL)");
}
} catch (Exception unused) {
}
try {
if (!doesExistsTable("new_study_plan_other")) {
this.wdb.execSQL("create table if not exists new_study_plan_other(serial INTEGER PRIMARY KEY , word TEXT , add_time INTEGER NOT NULL)");
}
} catch (Exception unused2) {
}
try {
if (!doesExistsTable("new_added")) {
this.wdb.execSQL("create table if not exists new_added(word TEXT PRIMARY KEY , details TEXT NOT NULL)");
}
} catch (Exception unused3) {
}
try {
if (!doesExistsTable("new_history")) {
this.wdb.execSQL("create table if not exists new_history(serial INTEGER PRIMARY KEY , word TEXT , add_time INTEGER NOT NULL)");
}
} catch (Exception unused4) {
}
if (!doesExistsTable("new_history_other")) {
this.wdb.execSQL("create table if not exists new_history_other(serial INTEGER PRIMARY KEY , word TEXT , add_time INTEGER NOT NULL)");
}
//Crash on the below line.
this.wdb.execSQL("INSERT INTO type VALUES ( NULL,'MORE')");
if (z) {
manageInThread();
}
}
initializeDatabase task:
private void initilizeDatabase(final int i, final boolean z) {
new AsyncTask<String, String, String>() {
protected void onPreExecute() {
try {
if (i == Constants.DB_VERSION) {
DictionaryActivity.this.progressMessageView.setVisibility(8);
} else {
DictionaryActivity.this.progressMessageView.setVisibility(0);
}
} catch (Exception e) {
LogUtils.log(DictionaryActivity.this, e);
}
}
protected String doInBackground(String... strArr) {
if (z) {
DatabaseHelper.backupInFile(DictionaryActivity.this, i);
}
DatabaseHelper.manageDatabase(DictionaryActivity.this, false);
try {
DictionaryActivity.this.databaseAccessor = new DatabaseAccessor(DictionaryActivity.this);
} catch (Exception e) {
e.printStackTrace();
}
DictionaryActivity.this.databaseAccessor.createTablesAndPorcess();
//Crash while executing above line.
DictionaryActivity.this.databaseAccessor.initTypeMapping(DictionaryActivity.this.IDSToPS, DictionaryActivity.this.PSToIDS, DictionaryActivity.this.PS_VALUES, DictionaryActivity.this.PS_IDS);
if (z) {
DictionaryActivity.this.databaseAccessor.loadWordFromFile(DictionaryActivity.this);
DictionaryActivity.this.databaseAccessor.restoreFile(DictionaryActivity.this, DictionaryActivity.this.getDatabasePath(Constants.BACKUP_FILE_NAME));
}
return null;
}
protected void onPostExecute(String str) {
try {
DictionaryActivity.this.mainViewAnimator.setDisplayedChild(1);
DictionaryActivity.this.addTabs(DictionaryActivity.TITLE_IDS);
if (DictionaryActivity.this.sharedPreferences.getInt(Constants.KEY_LAST_SHOWN_POPUP_MESSAGE_ID, 0) != 5) {
DictionaryActivity.this.showInitialMessage(false);
} else {
DictionaryActivity.this.manageAutoPopups();
}
DictionaryActivity.this.showSharedText(DictionaryActivity.this.getIntent());
Utils.createShortCut(DictionaryActivity.this, DictionaryActivity.class);
Utils.manageClipboardAndNotificationbar(DictionaryActivity.this);
try {
DictionaryActivity.this.isTTSRequested = false;
Intent intent = new Intent();
intent.setAction("android.speech.tts.engine.CHECK_TTS_DATA");
DictionaryActivity.this.startActivityForResult(intent, DictionaryActivity.CHECK_TTS);
} catch (Exception e) {
e.printStackTrace();
}
DictionaryActivity.this.showHideOCR(true);
DictionaryActivity.this.showOverlayPermissionPopupIfRequired();
} catch (Exception e2) {
if (!(e2 instanceof ActivityNotFoundException)) {
LogUtils.log(DictionaryActivity.this, e2);
}
}
DictionaryActivity.this.isExitingOk = true;
if (DictionaryActivity.this.IDSToPS.size() == 0) {
DictionaryActivity.this.resetDatabase();
}
}
}.execute();
}
The error is coming when I call createTablesAndProcess in the initialize method and at this.wdb.execSQL("INSERT INTO type VALUES ( NULL,'MORE')"); line. Let me know in the comments if you want more logs.
Update - Logcat:
2019-06-19 13:31:56.289 20450-20479/com.hdictionary.gu E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.hdictionary.gu, PID: 20450
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
Caused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: type.ps (code 2067)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:734)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1677)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1606)
at com.bappi.db.DatabaseAccessor.createTablesAndPorcess(DatabaseAccessor.java:152)
at com.hdictionary.gu.DictionaryActivity$10.doInBackground(DictionaryActivity.java:1130)
at com.hdictionary.gu.DictionaryActivity$10.doInBackground(DictionaryActivity.java:1100)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
It is a simple error. Each element of column ps in the table type should be unique since you created the table that way. But at the time of executing the statement INSERT INTO type VALUES ( NULL,'MORE') It somehow have the same value (if it is the first column, then a NULL) in the column ps already.
I have one connection for each table in a database like the below, How Can I use Two Table in a time?? My Main trouble is how connect to Two Table in a time to use them. Please somebody tell me about that
part of My code is:
public bool createDataBase()
{
try
{
using (var connection = new
SQLiteConnection(System.IO.Path.Combine(folder, "Plans.db")))
{
connection.CreateTable<Plan>();
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
public bool createDataBase2()
{
try
{
using (var connection = new SQLiteConnection(System.IO.Path.Combine(folder, "PlanDoned.db")))
{
connection.CreateTable<Plan>();
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
public bool insertIntoTablePlanDoned(Plan plan)
{
try
{
using (var connection = new
SQLiteConnection(System.IO.Path.Combine(folder, "PlanDoned.db")))
{
//connection.Query<Plan>("UPDATE Plan SET PlanName=?,PlanDate=?,PlanDesc=? where Id=?", plan.PlanName, plan.PlanDate, plan.PlanDesc, plan.Id);
//return true;
connection.Query<Plan>("insert into PlanDoned select * from Plans where Id=?", plan.Id);
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
use ATTACH DATABASE 'Database2Path' As 'Database2Name';
Then use both Database1 and Database2 in the same query i.e.:
INSERT INTO Database2Name.Table SELECT Column1, Column2 FROM Database1.Table
I'm using azure sdk for android and follow the tutorial https://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-data/.
When I'm trying to connect and insert data to mobile service table all is ok, but when I query the table in activity my app gets stuck, though there are only several entries in the table and execute method successfully returns Future.
public static MobileServiceClient mClient;
public static void connect(Context context) {
try {
mClient = new MobileServiceClient(storageLink, key, context);
} catch (MalformedURLException e) {
Log.e("AzureService.connect", "Storage access failed" + storageLink);
}
}
public static InstallationData get(final String deviceId) {
MobileServiceTable<InstallationData> table= mClient.getTable(InstallationData.class);
final MobileServiceList<InstallationData> result;
try {
result = table.where().field("deviceid").eq(deviceId).execute().get();
for (InstallationData item : result) {
return item;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
public static void store(final InstallationData item) {
mClient.getTable(InstallationData.class).insert(item, new TableOperationCallback<InstallationData>() {
public void onCompleted(InstallationData entity, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
Log.d("AzureService.store()", "Data about " + item.getDeviceid() + "" + "is successfully updated");
} else {
exception.printStackTrace();
Log.e("AzureService.store()", "Data about " + item.getDeviceid() + "" + "is failed to update");
}
}
});
}
Thank you in advance!
I try to implement sample apk for KIOSK .I have many tables. So I would like to implement common methods for all database tasks(select , insert , update , delete ). Now I create select method in one class like this..
public List<OrgcodeInfo> OrgList(String sql) {
cursor = null;
try {
cursor = mDb.rawQuery(sql, null);
_listOrgcodeInfo = new ArrayList<OrgcodeInfo>();
while (cursor.moveToNext()) {
_OrgcodeInfo = new OrgcodeInfo();
_OrgcodeInfo.setOrgcode(cursor.getString(cursor
.getColumnIndex("Org Code")));
_OrgcodeInfo.setOrgName(cursor.getString(cursor
.getColumnIndex("Shop Name")));
_listOrgcodeInfo.add(_OrgcodeInfo);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
cursor.close();
mDb.close();
}
return _listOrgcodeInfo;
}
This is OK for small tasks.But I have many tasks for data transaction. I create object for every table as OrgcodeInfo and set data every time.
How can I do it.
public class DBconnection {
SQLiteDatabase database;
public DBconnection(Context context){
try {
// TODO Auto-generated constructor stub
database=context.openOrCreateDatabase("hslogin",SQLiteDatabase.OPEN_READWRITE,null);
database.execSQL("create table if not exists login(username varchar(40) PRIMARY KEY,password varchar(40))");
database.execSQL("create table if not exists instructions(sourcedestination varchar(100) ,instruction varchar(80),lattitude varchar(100),longitude varchar(100))");
} catch (Exception e) {
// TODO: handle exception
}
}
public int putData(String sql) {
int i;
try {
database.execSQL(sql);
i=1;
} catch (Exception e) {
i=0;
// TODO: handle exception
}
return i;
}
public Cursor getData(String sql) {
Cursor cursor=null;
try {
cursor=database.rawQuery(sql, null);
} catch (Exception e) {
// TODO: handle exception
}
return cursor;
}}
In my android app I am using ormlite. Now I want to create some testcases for the db helper methods. I do not know how this should work properly. The database need to be created in my testcase before the concrete test can start. For example I want to test if a user will be created as expected. For this I have a addUser Method which should be tested, but how can this be done?
Currently I created a TestProject with a TestCase for my DBManager-Class.
Here is my DBHelper class
public class DBHelper extends OrmLiteSqliteOpenHelper{
private static final String DATABASE_NAME = "pdixattach.db";
private static final int DATABASE_VERSION = 4;
private static final String TAG = DBHelper.class.getSimpleName();
private static DBHelper _helperInstance;
private Dao<Attachment, Integer> attachmentDao = null;
private Dao<User, Integer> userDao = null;
private Dao<Comment, Integer> commentDao = null;
private Dao<Job, Integer> jobDao = null;
private Dao<Target, Integer> targetDao = null;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db, ConnectionSource source) {
Log.i(TAG, "onCreate");
try{
dropTables(source);
TableUtils.createTable(source, Attachment.class);
TableUtils.createTable(source, User.class);
TableUtils.createTable(source, Comment.class);
TableUtils.createTable(source, Target.class);
TableUtils.createTable(source, Job.class);
TableUtils.createTable(source, ConfigurationParameter.class);
} catch (Exception e){
Log.e(TAG, "error while creating tables " + e.getMessage());
throw new RuntimeException(e);
}
}
#Override
public void onUpgrade(final SQLiteDatabase db, final ConnectionSource connectionSource, final int oldVersion, final int newVersion) {
Log.i(TAG, "onUpgrade");
try {
dropTables(connectionSource);
onCreate(db, connectionSource);
} catch (SQLException e) {
Log.e(TAG, "error while upgrading tables " + e.getMessage());
throw new RuntimeException(e);
}
// after we drop the old databases, we create the new ones
onCreate(db, connectionSource);
}
private void dropTables(final ConnectionSource connectionSource)
throws SQLException {
TableUtils.dropTable(connectionSource, Attachment.class, true);
TableUtils.dropTable(connectionSource, User.class, true);
TableUtils.dropTable(connectionSource, Target.class, true);
TableUtils.dropTable(connectionSource, Job.class, true);
TableUtils.dropTable(connectionSource, Comment.class, true);
TableUtils.dropTable(connectionSource, ConfigurationParameter.class, true);
}
public Dao<Attachment, Integer> getAttachmentDao() throws SQLException {
if (this.attachmentDao == null) {
this.attachmentDao = getDao(Attachment.class);
}
return this.attachmentDao;
}
public Dao<User, Integer> getUserDao() throws SQLException {
if (this.userDao == null) {
this.userDao = getDao(User.class);
}
return this.userDao;
}
public Dao<Comment, Integer> getCommentDao() throws SQLException {
if (this.commentDao == null) {
this.commentDao = getDao(Comment.class);
}
return this.commentDao;
}
public Dao<Target, Integer> getTargetDao() throws SQLException {
if (this.targetDao == null) {
this.targetDao = getDao(Target.class);
}
return this.targetDao;
}
public Dao<Job, Integer> getJobDao() throws SQLException {
if (this.jobDao == null) {
this.jobDao = getDao(Job.class);
}
return this.jobDao;
}
/**
* Close the database connections and clear any cached DAOs.
*/
#Override
public void close() {
super.close();
_helperInstance = null;
this.attachmentDao = null;
this.commentDao = null;
this.jobDao = null;
this.targetDao = null;
this.userDao = null;
}
}
and my DBManager which I want to test, for example the storeUser Method
public class DBManager {
private DBHelper helper;
private static DBManager uniqueInstance;
private static final String TAG = DBManager.class.getSimpleName();
public DBManager(Context context) {
helper = new DBHelper(context);
}
public static void init(Context context) {
if (uniqueInstance == null) {
uniqueInstance = new DBManager(context);
}
}
public static DBManager getInstance() {
return uniqueInstance;
}
public boolean addUser(User u) {
boolean retVal = false;
if (u == null) {
throw new IllegalArgumentException("user must not be null");
}
try {
helper.getUserDao().create(u);
retVal = true;
} catch (SQLException e) {
Log.e(TAG, "error while adding user to db " + e.getMessage());
}
return retVal;
}
public boolean addServiceEndpoint(String endpoint) {
Log.d(TAG, "adding Service Endpoint " + endpoint);
boolean retVal = false;
if (endpoint == null) {
throw new IllegalArgumentException("endpoint must not be null");
}
try {
Target t = new Target(endpoint);
int result = helper.getTargetDao().create(t);
Log.d(TAG, "creating target entry resulted with value " + result);
retVal = (result == 1);
} catch (SQLException e) {
Log.e(TAG,"error while adding target to db, with service endpoint " + endpoint + "error" + e.getMessage());
}
return retVal;
}
public List<Target> getAllTargets() {
List<Target> retVal = new ArrayList<Target>();
try {
retVal = helper.getTargetDao().queryForAll();
} catch (SQLException e) {
Log.e(TAG,
"error while retrieving service endpoints, error" + e.getMessage());
}
return retVal;
}
public User storeUser(String username, String hashedPw, Target target,
boolean storeLogin) {
User loggedInUser = null;
int loginState = (storeLogin) ? 1 : 0;
if (username == null || hashedPw == null || target == null) {
throw new IllegalArgumentException(
"cannot store login with empty/null values");
}
try {
QueryBuilder<User, Integer> queryBuilder = helper.getUserDao().queryBuilder();
Where<User, Integer> where = queryBuilder.where();
where.eq(User.USERNAME, username)
.and().eq(User.TARGET_ID, target.getServiceEndpoint());
PreparedQuery<User> prepareStmt = queryBuilder.prepare();
List<User> userList = helper.getUserDao().query(prepareStmt);
if (userList.isEmpty()) {
Log.d(TAG, "no user found with this name in the db, need to store it");
User newUser = new User(username, hashedPw, target);
newUser.setStored(loginState);
addUser(newUser);
userList = helper.getUserDao().query(prepareStmt);
loggedInUser = userList.get(0);
} else {
Log.d(TAG, "found at least one user with username " + username + " target " + target);
for (User u : userList) {
if (u.getPassword().equals(hashedPw)) {
Log.d(TAG, "password is equal to the one in db");
}
else {
u.setPassword(hashedPw);
}
// setze diesen User als aktiv!
u.setStatus(1);
u.setStored(loginState);
helper.getUserDao().update(u);
loggedInUser = u;
}
}
} catch (SQLException e) {
Log.d(TAG, "error while storing login" + e.getMessage());
}
return loggedInUser;
}
public Comment addComment(Comment cmt) {
Comment retVal = null;
if (cmt == null) {
throw new IllegalArgumentException("cannot create a comment entry in database without comment");
}
try {
retVal = helper.getCommentDao().createIfNotExists(cmt);
} catch (SQLException e) {
e.printStackTrace();
}
return retVal;
}
public Attachment addAttachment(Attachment att) {
if (att == null) {
throw new IllegalArgumentException(
"cannot create attachment entry in database without attachment");
}
Attachment dbAttach = null;
try {
dbAttach = helper.getAttachmentDao().createIfNotExists(att);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dbAttach;
}
public Job addJob(Job job) {
Job dbJob = null;
if (job == null) {
throw new IllegalArgumentException(
"no job given, cannot create an entry");
}
try {
QueryBuilder<Job, Integer> queryBuilder = helper.getJobDao()
.queryBuilder();
Where<Job, Integer> where = queryBuilder.where();
if (job.getInstanceId() == null)
where.isNull(Job.INSTANCE_ID);
else
where.eq(Job.INSTANCE_ID, job.getInstanceId());
where.and().eq(Job.COMMENT_ID, job.getComment().getComment()).and()
.eq(Job.ATTACH_ID, job.getAtach().getAttUri()).and()
.eq(Job.STATUS, "0").and()
.eq(Job.TARGET_ID, job.getTarget().getServiceEndpoint());
PreparedQuery<Job> prepareStmt = queryBuilder.prepare();
Log.d(TAG, "querystring is " + prepareStmt.getStatement());
List<Job> jobList = helper.getJobDao().query(prepareStmt);
if (jobList.isEmpty()) {
Log.d(TAG, "no job with these parameters given, need to create one");
Log.d(TAG, "job id is " + job.getId());
dbJob = helper.getJobDao().createIfNotExists(job);
Log.d(TAG, "dbJob id is " + dbJob.getId());
} else {
Log.d(TAG,
"job does already exists for this parameters, wont create new");
dbJob = jobList.get(0);
// hier comment und status usw updaten
}
} catch (SQLException e) {
Log.d(TAG, "Exception during adding a job to db: " + e.getMessage());
}
return dbJob;
}
public void attachInstanceIdToJob(String instanceId, long jobId) {
Log.d(TAG, "attaching instance id " + instanceId + " to job with id " + jobId);
try {
Job job = helper.getJobDao().queryForId((int) jobId);
if (job != null){
job.setInstanceId(instanceId);
helper.getJobDao().update(job);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
Log.d(TAG, "error while attaching instance id " + instanceId + " to job with id " + jobId);
}
}
public List<Job> getAllOpenJobs() {
List<Job> jobList = null;
QueryBuilder<Job, Integer> queryBuilder;
try {
queryBuilder = helper.getJobDao()
.queryBuilder();
Where<Job, Integer> where = queryBuilder.where();
where.eq(Job.STATUS, JobStatusEnum.OPEN.getState())
.or().eq(Job.STATUS, JobStatusEnum.RETRY.getState());
;
PreparedQuery<Job> prepareStmt = queryBuilder.prepare();
Log.d(TAG, "querystring is " + prepareStmt.getStatement());
jobList = helper.getJobDao().query(prepareStmt);
} catch (SQLException e) {
Log.d(TAG, "error while retrieving open jobs from db" + e.getMessage());
}
return jobList;
}
public void getDataForJob(Job j, User u, Attachment att, Target target, Comment comment) {
try {
if (j != null){
helper.getUserDao().refresh(j.getUser());
helper.getAttachmentDao().refresh(j.getAtach());
helper.getTargetDao().refresh(j.getTarget());
helper.getCommentDao().refresh(j.getComment());
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public User getCurrentStoredUser(){
try {
List<User> users = helper.getUserDao().queryForAll();
for (User u: users){
if (u.getStored() == 1){
return u;
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void updateJob(Job j) {
if (j != null){
try {
helper.getJobDao().update(j);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* The status of the given user will be configured to stored. All others will be set to unstored
* #param loggedInUser
*/
public void setUserStatusToStored(User loggedInUser) {
List<User> listOfUsers;
try {
listOfUsers = helper.getUserDao().queryForAll();
for (User u: listOfUsers){
if (u.equals(loggedInUser)){
u.setStatus(UserStatusEnum.STORED.getState());
}
else{
u.setStatus(UserStatusEnum.UNSTORED.getState());
}
helper.getUserDao().update(u);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and my TestClass
public class DBManagerTest
extends TestCase
{
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testDBManager() {
fail( "Not yet implemented" );
}
}
Can someone help me with shat, I guess once the first test is running the others should be clear.
Thanks