I my connecting to a MySQL database that is on PC from my android application.
I am using java.sql.jdb for that. Now I want my result set to get in android.database.cursor??
How can I do that..??
Thats my code I am using in android application its getting the results for database but can't cast to Cursor:
Connection connect = null;
ResultSet resultSet = null;
Statement statement = null;
try {
connect = DriverManager.getConnection("jdbc:mysql://"+DbHelper.DB_Path+"/"+DbHelper.DB_Name+"?"
+ "user="+ DbHelper.DB_UserName+ "&password="+ DbHelper.DB_Pass);
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("Select * from btag_store "+
"Where "+
"guid='"+filterArgs+"'");
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Cursor cc;
cc = (Cursor) resultSet; // error in type casr
I know that type casting will give me error, but is there any other way for that..??
Thanks
To put it simply, you cannot. Unless you are willing to do all the work to define an object that implements the Cursor interface and uses a ResultSet to fulfil Cursor's implementation details. That would be somewhat silly, though, as the ResultSet object is already designed to iterate over results returned from the database. The cleanest approach is to use the ResultSet object as it was intended.
What Dave said is correct. My database items were constructed upon Cursor (Sqlite) but I need the same entrypoint wiht MySQL. So I tried this:
I created a base class
AbstractCursorGen.java:
import android.database.Cursor;
import java.sql.ResultSet;
public abstract class AbstractCursorGen {
protected Cursor c;
protected ResultSet rs;
public abstract int getColumnIndex(String iName);
public abstract String getString(String iName);
public abstract int getInt(String iName);
public abstract long getLong(String iName);
public abstract boolean moveToNext();
public abstract void close();
}
Then the one using Cursor will hold the instance of cursor. There is an additional benefit by getting result giving directly the column string. My code uses this for SQLite.
CursonGen.Java:
import android.database.Cursor;
public class CursorGen extends AbstractCursorGen{
public CursorGen(Cursor c)
{
this.c = c;
}
public int getColumnIndex(String iName)
{
return c.getColumnIndex(iName);
}
public String getString(String iName){
return c.getString(getColumnIndex(iName));
}
public int getInt(String iName){
return c.getInt(getColumnIndex(iName));
}
public long getLong(String iName){
return c.getLong(getColumnIndex(iName));
}
public boolean moveToNext()
{
return c.moveToNext();
}
public void close()
{
c.close();
}
}
And one built upon the resultset. This is used for MySQL results
ResultSetGen.java
import android.util.Log;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ResultSetGen extends AbstractCursorGen{
public ResultSetGen(ResultSet rs)
{
this.rs = rs;
}
public int getColumnIndex(String iName)
{
try {
return rs.findColumn(iName);
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public String getString(String iName){
try {
return rs.getString(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return null;
}
}
public int getInt(String iName){
try {
return rs.getInt(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public long getLong(String iName){
try {
return rs.getLong(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public boolean moveToNext()
{
try {
return rs.next();
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return false;
}
}
public void close()
{
try {
rs.close();
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
}
}
}
The trick is providing implementation only for the methods I'm actually using.
This is finally called by (one example)
public Person(AbstractCursorGen cursor)
{
setFromCursor(cursor);
}
protected void setFromCursor(AbstractCursorGen cursor)
{
PersonID = cursor.getLong ( COLUMN_PERSON_ID);
ClusterID = cursor.getInt ( COLUMN_CLUSTER_ID);
Name = cursor.getString ( COLUMN_NAME);
.....
}
Hope this helps.
Related
Summary
SQLiteDatabase.insertOrThrow() executes, does not throw an exception, and returns a positive integer; however, the record is not written to the database.
Details
I am implementing the repository pattern, and have a generic base repository.
public class BaseRepository<T> implements Repository<T> {
private enum Operation {
Add, Update, Delete
}
private final SQLiteOpenHelper openHelper;
private final String tableName;
private final Mapper<T, ContentValues> toContentValues;
private final Mapper<Cursor, T> toTypeMapper;
public BaseRepository(Context context, String tableName, Mapper<T, ContentValues> toContentValues,
Mapper<Cursor, T> toTypeMapper) {
this.openHelper = new DbOpenHelper(context);
this.tableName = tableName;
this.toContentValues = toContentValues;
this.toTypeMapper = toTypeMapper;
}
#Override
public void add(T item) {
transaction(Operation.Add, item, null);
}
#Override
public void update(T item, String filter) {
transaction(Operation.Update, item, filter);
}
#Override
public void delete(String filter) {
transaction(Operation.Delete, null, filter);
}
private void transaction(Operation operation, T item, String filter) {
final SQLiteDatabase database = openHelper.getWritableDatabase();
database.beginTransaction();
try {
switch (operation) {
case Add:
try { // For debugging, to catch any possible exception
ContentValues values = toContentValues.map(item);
long result = database.insertOrThrow(tableName, null, values);
String temp = ""; // For debugging
} catch (Exception e) {
String message = e.getMessage(); // For debugging
}
break;
case Update:
database.update(tableName, toContentValues.map(item), filter, null);
break;
case Delete:
database.delete(tableName, filter, null);
break;
}
} finally {
database.endTransaction();
database.close();
}
}
}
It gets into the transaction() method, and runs the database.insert() method. I have set breakpoints and have examined the table name and the values. The table name is correct and the values is correct. The method runs and returns a positive integer, indicating that the insert was successful. However, when I examine the database, the record is not inserted.
I have methods to get data and they are working correctly. If I manually add a row, the get method works successfully.
Any thoughts on what is going on here? I've been stuck on this for hours.
Thanks!
Figured it out. I forgot to run database.setTransactionSuccessful():
private void transaction(Operation operation, T item, String filter) {
final SQLiteDatabase database = openHelper.getWritableDatabase();
database.beginTransaction();
try {
switch (operation) {
case Add:
try { // For debugging, to catch any possible exception
ContentValues values = toContentValues.map(item);
long result = database.insertOrThrow(tableName, null, values);
String temp = ""; // For debugging
} catch (Exception e) {
String message = e.getMessage(); // For debugging
}
break;
case Update:
database.update(tableName, toContentValues.map(item), filter, null);
break;
case Delete:
database.delete(tableName, filter, null);
break;
}
database.setTransactionSuccessful(); // Added this.
} finally {
database.endTransaction();
database.close();
}
}
i'm using ORMlite library in android and i get this error random and i dont know whats that and how to modrate:
Caused by: java.lang.IllegalStateException: Could not get next result for class [Ljava.lang.String;
at com.j256.ormlite.stmt.SelectIterator.next
i get this error when i'm using this method to get single column :
public static List getSingleColumn(String query) {
List<String> columnes = null;
try {
columnes = G.CATEGORY.queryRaw(query, new RawRowMapper<String>() {
#Override
public String mapRow(String[] columnNames, String[] resultColumns) throws android.database.SQLException {
return resultColumns[0];
}
}).getResults();
} catch (SQLException e) {
e.printStackTrace();
}
return columnes;
}
or this code:
List unread_messages = G.DBHELPER.getSingleColumn("SELECT SUM(read_status) FROM messageslist");
Try change method to this:
public static String getSingleColumn(String query) {
String columnes = null;
try {
columnes = G.CATEGORY.queryRaw(query, new RawRowMapper<String>() {
#Override
public String mapRow(String[] columnNames, String[] resultColumns) throws android.database.SQLException {
return resultColumns[0];
}
}).getFirstResult();
} catch (SQLException e) {
e.printStackTrace();
}
return columnes;
}
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;
}}
I have problem which many have and I think, that I tried all solutions, but I have not found the right solution yet.
My existing database "base.sqlite3" is in "assets" folder, contains three tables.
When I want to do query, appears error, that table is not there.
(In code are possible syntax errors, cause I translated code)
public class Sqlite extends SQLiteOpenHelper {
private final Context myContext;
public SQLiteDatabase base;
private static String path ="/data/data/" + "com.example.myexample" + "/databases/";
private static String name = "base.sqlite3";
private static String p = path + name;
public Sqlite(Context context){
super(context, ime, null, 1);
this.myContext = context;
createDatabase();
}
#Override
public void onCreate(SQLiteDatabase base) {}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
#Override
public synchronized void close()
{
if(base != null)
base.close();
super.close();
}
public void createDatabase()
{
boolean exist1 = checkDatabase();
if(exist1){}
else
{
base = this.getReadableDatabase();
base.close();
copyDatabase();
}
}
private boolean checkDatabase()
{
SQLiteDatabase check = null;
try
{
check = SQLiteDatabase.openDatabase(p, null, SQLiteDatabase.OPEN_READONLY);
}
catch(SQLiteException e)
{ }
if(check != null)
{
check.close();
}
return check != null ? true : false;
}
private void copyDatabase()
{
InputStream dat = null;
try {
dat = myContext.getAssets().open(name);
} catch (IOException e) {
e.printStackTrace();
}
OutputStream dat2 = null;
try {
dat2 = new FileOutputStream(p);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] buffer = new byte[1024];
int length;
try {
while ((length = dat.read(buffer))>0)
{
dat2.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
dat2.flush();
dat2.close();
dat.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void openDatabase()
{
base = SQLiteDatabase.openDatabase(p, null, SQLiteDatabase.OPEN_READONLY);
}
public Cursor SelectSomething(String sql)
{
base = SQLiteDatabase.openDatabase(p, null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = base.rawQuery(sql,null);
return cursor;
}
}
Thank you so much for all help!
As already was stated in the comment to this answer, the code from
this article is
" old, outdated, dreadful (concatenation to create file paths?), and problematic",
and it appears you are not the first to encounter problems with it.
Also, in the same comment to the same answer, it is proposed to use SQLiteAssetHelper. Consider trying it.
I'm currently stuck with the following situation;
Basically I've got a Work class, which has a ForeignCollection of WorkTasks.
I'd like to simply receive all WorkTasks, linked to Work object.
If I query for all WorkTasks, I do get a list of results but with 'work = null'. So it can't make any link to the correct Work object.
Resulting in no results with querying for the work_id and an empty list in Work itself.
I've seen examples and questions about this countless of times but apparently im missing out on something.
Below is the code that im using which is relevant;
The DatabaseHelper;
#Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
try {
applicantDao = DaoManager.createDao(connectionSource, Applicant.class);
educationDao = DaoManager.createDao(connectionSource, Education.class);
workDao = DaoManager.createDao(connectionSource, Work.class);
workTaskDao = DaoManager.createDao(getConnectionSource(), WorkTask.class);
onlinePersonDao = DaoManager.createDao(connectionSource, OnlinePerson.class);
institutionDao = DaoManager.createDao(connectionSource, Institution.class);
lessonDao = DaoManager.createDao(connectionSource, Lesson.class);
TableUtils.createTable(connectionSource, Applicant.class);
TableUtils.createTable(connectionSource, Education.class);
TableUtils.createTable(connectionSource, Work.class);
TableUtils.createTable(connectionSource, Institution.class);
TableUtils.createTable(connectionSource, Lesson.class);
TableUtils.createTable(connectionSource, OnlinePerson.class);
TableUtils.createTable(connectionSource, Reference.class);
TableUtils.createTable(connectionSource, WorkTask.class);
[....]
public Dao<WorkTask, Integer> getWorkTaskDao() {
if (null == workTaskDao) {
try {
workTaskDao = getDao(WorkTask.class);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return workTaskDao;
}
The database manager:
public List<Experience> getAllWork() {
List<Experience> exp = null;
try {
exp = getHelper().getWorkDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return exp;
}
public List<WorkTask> getAllWorkTask() {
List<WorkTask> workTask = null;
try {
workTask = getHelper().getWorkTaskDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return workTask;
}
public List<WorkTask> getWorkTaskByWorkId(int workId) {
List<WorkTask> workTasks = null;
try {
workTasks = getHelper().getWorkTaskDao().queryForEq("work_id", workId);
} catch (SQLException e) {
e.printStackTrace();
}
return workTasks;
}
public void addWork(Collection<Work> jobs) {
try {
for (Experience work : jobs) {
Work w = (Work) work;
// Add nested child first
this.addInstitution(w.institution);
this.addWorkTask(w.tasks);
getHelper().getWorkDao().createOrUpdate(w);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void addWorkTask(Collection<WorkTask> worktasks) {
try {
for (WorkTask wt : worktasks) {
getHelper().getWorkTaskDao().createOrUpdate(wt);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
The list from the work model (gets a pre-filled id from an abstract parent):
#ForeignCollectionField(eager = true)
#SerializedName("tasks")
public Collection<WorkTask> tasks;
public ArrayList<WorkTask> getTasks(){
ArrayList<WorkTask> taskList = new ArrayList<WorkTask>();
Iterator iterator = tasks.iterator();
while(iterator.hasNext()){
WorkTask task = (WorkTask) iterator.next();
taskList.add(task);
}
return taskList;
}
The WorkTask :
public class WorkTask {
/**
* Auto-incremented id for the ORMLite-SQLite database
*/
#DatabaseField(generatedId = true)
public int id;
/**
* Foreign field id for the ORMLite-SQLite database
*/
#DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true, columnName = "work_id")
public Work work;
And finally all the things that are failing me:
ArrayList<WorkTask> tasks_iterated = work.getTasks();
ArrayList<WorkTask> tasks_id = (ArrayList<WorkTask>) DatabaseManager.getInstance()
.getWorkTaskByWorkId(work.id);
ArrayList<WorkTask> tasks = (ArrayList<WorkTask>) DatabaseManager.getInstance().getAllWorkTask();
This eventually leaves me with:
tasks_iterated = empty
tasks_id = empty
tasks = a full list of my tasks but all with the attribute 'work = null' so I can't place them to the correct Work object.
Fixed it by changing my adding method to:
public void addWorkTask(Collection<WorkTask> worktasks, Work work) {
try {
for (WorkTask wt : worktasks) {
wt.work = work;
getHelper().getWorkTaskDao().createOrUpdate(wt);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
Not sure if it's the only way to do this though. Seems a bit weird i'd have to do this manually.