I've got an error trying to do different test on a DBTest from sunshine App on android studio. I can´t figure out whats going on.
Here is the error message
junit.framework.AssertionFailedError
at com.example.juandavid.sunshine.data.TestDb.insertLocation(TestDb.java:196)
at com.example.juandavid.sunshine.data.TestDb.testLocationTable(TestDb.java:117)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1729)
junit.framework.AssertionFailedError
at com.example.juandavid.sunshine.data.TestDb.insertLocation(TestDb.java:196)
at com.example.juandavid.sunshine.data.TestDb.testWeatherTable(TestDb.java:130)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1729)
I'm learning and this is a new kind of error for me because I´m also trying to learn tables, databases and testing at the same time.
And here is the code:
package com.example.juandavid.sunshine.data;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
public class TestDb extends AndroidTestCase {
public static final String LOG_TAG = TestDb.class.getSimpleName();
// Since we want each test to start with a clean slate
void deleteTheDatabase() {
mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME);
}
/*
This function gets called before each test is executed to delete the database. This makes
sure that we always have a clean test.
*/
public void setUp() {
deleteTheDatabase();
}
public void testLocationTable() {
// First step: Get reference to writable databas
//line 117 com.example.juandavid.sunshine.data.TestDb.testLocationTable
insertLocation();
}
public void testWeatherTable() {
// First insert the location, and then use the locationRowId to insert
// the weather. Make sure to cover as many failure cases as you can.
deleteTheDatabase();
//line 130 com.example.juandavid.sunshine.data.TestDb.testWeatherTable error when inserLocation called
long locationRowId = insertLocation();
assertFalse("Error: Location Not Inserted Correctly", locationRowId == -1L);
// Instead of rewriting all of the code we've already written in testLocationTable
// we can move this code to insertLocation and then call insertLocation from both
// tests. Why move it? We need the code to return the ID of the inserted location
// and our testLocationTable can only return void because it's a test.
// First step: Get reference to writable database
WeatherDbHelper dbHelper= new WeatherDbHelper(mContext);
SQLiteDatabase db =dbHelper.getWritableDatabase();
// Create ContentValues of what you want to insert
// (you can use the createWeatherValues TestUtilities function if you wish)
ContentValues weatherValues = TestUtilities.createWeatherValues(locationRowId);
// Insert ContentValues into database and get a row ID back
long weatherRowId = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, weatherValues);
assertTrue(weatherRowId != -1);
// Query the database and receive a Cursor back
Cursor weatherCursor = db.query(
WeatherContract.WeatherEntry.TABLE_NAME, // Table to Query
null, // leaving "columns" null just returns all the columns.
null, // cols for "where" clause
null, // values for "where" clause
null, // columns to group by
null, // columns to filter by row groups
null // sort order
);
// Move the cursor to a valid database row
assertTrue("Error: No records returned from location query", weatherCursor.moveToFirst()); // No se econtro nada
// Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("testInsertReadDb weatherEntry failed to validate",
weatherCursor, weatherValues);
assertFalse( "Error: More than one record returned from weather query",
weatherCursor.moveToNext() );
// Finally, close the cursor and database
weatherCursor.close();
dbHelper.close();
}
public long insertLocation() {
WeatherDbHelper dbHelper = new WeatherDbHelper(mContext);
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Second Step: Create ContentValues of what you want to insert
// (you can use the createNorthPoleLocationValues if you wish)
ContentValues testValues = TestUtilities.createNorthPoleLocationValues();
// Third Step: Insert ContentValues into database and get a row ID back
long locationRowId;
//Line 196 com.example.juandavid.sunshine.data.TestDb.insertLocation(TestDb.java:196)
locationRowId = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, testValues);
// Verify we got a row back.
assertTrue(locationRowId != -1);
// Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made
// the round trip.
// Fourth Step: Query the database and receive a Cursor back
// A cursor is your primary interface to the query results.
Cursor cursor = db.query(
WeatherContract.LocationEntry.TABLE_NAME, // Table to Query
null, // all columns
null, // Columns for the "where" clause
null, // Values for the "where" clause
null, // columns to group by
null, // columns to filter by row groups
null // sort order
);
// Move the cursor to a valid database row and check to see if we got any records back
// from the query
assertTrue( "Error: No Records returned from location query", cursor.moveToFirst() );
// Fifth Step: Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("Error: Location Query Validation Failed",
cursor, testValues);
// Move the cursor to demonstrate that there is only one record in the database
assertFalse( "Error: More than one record returned from location query",
cursor.moveToNext() );
// Sixth Step: Close Cursor and Database
cursor.close();
db.close();
return locationRowId;
}
}
The test function insertLocation() doesn´t generate that error and is called by the testLocationTable and then again by the testWeatherTable.
Looking forward to your kind reply.
Regards,
Juan
Related
The Account table contains 2 rows when the query is executed it returns only one row.
when the database is opened in SQLite(Software to view sql database on pc) it shows 2 proper rows.
HashMap<String, Integer> returnAccount(Context context)
{
HashMap<String,Integer> account = new HashMap<String, Integer>();
try
{
// Query in question
String statement = "SELECT * FROM `Account`;";
c = mydatabase.rawQuery(statement,null);
if(c.moveToFirst())
{
do {
Log.e("Count", String.valueOf(c.getCount()));
}while (c.moveToNext());
}
}
I tried deleting the entire table and rechecked the all the queries but nothing helped.
I expected all (2) rows.
2019-07-12 18:06:06.780 5663-5663/com.prasad.budgetmanager E/Count: 1
This are the logged data.
Entire Code is at https://github.com/prasad610/BugetManager/blob/master/app/src/main/java/com/prasad/budgetmanager/ExtraFunctions.java
Actual database content
Remove this line.
//Log.e("Move to next", String.valueOf(c.moveToNext()));
The c.moveToNext() is already moved the cursor to Next value. so the while loop will return false it will not execute the next value.
I am developing an Android application with an SQLite3 database holding some of the data for offline access. I am trying to query the database using rawQuery, and a WHERE clause querying for a String. However, it's not returning any results, and neither is SQLite3 on the command line using the same Query, however a copy of the database in MySQL format executes the query just fine and gets the correct results.
Here is my code:
String query = "SELECT id FROM plaques WHERE subject = ?";
String subjectName = "Florence Nightingale";
Cursor cursor = db.rawQuery(query, new String[]{subjectName});
if (cursor.moveToFirst()) {
do {
try {
int id = cursor.getInt(cursor.getColumnIndex("id"));
} catch (Exception e) {
e.printStackTrace();
}
} while (cursor.moveToNext());
}
cursor.close();
(the database is being selected, using the Context and this is working).
So the query (SELECT id FROM plaques WHERE subject='Florence Nightingale' works perfectly in MySQL on an exact copy of the database/table, but not in SQLite3. cursor.movetoFirst() is returned as false, indicating no results are returned). Does SQLite3 encode the text in a different way or something? If I try to a query where the WHERE clause selects a int value, the query works fine and returns the expected results.
I want to execute the following SQL command with one JdbcRowSet object:
INSERT INTO Authors (FirstName,LastName) VALUES ('Sue', 'Smith')
I know that i can execute with Connection and Satements objects, but i want to do this with the interface JdbcRowSet, because one JdbcRowSet object is updatable and scrollable by default.
My code is:
public class JdbcRowSetTest
{
public static final String DATABASE_URL = "jdbc:mysql://localhost/books";
public static final String USERNAME = "Ezazel";
public static final String PASSWORD = "Ezazel";
public JdbcRowSetTest()
{
try
{
JdbcRowSet rowSet = new JdbcRowSetImpl();
rowSet.setUrl( DATABASE_URL );
rowSet.setUsername( USERNAME );
rowSet.setPassword( PASSWORD );
rowSet.setCommand( "INSERT INTO Authors (FirstName,LastName) VALUES ('Sue', 'Smith')" );
rowSet.execute();
}
catch( SQLException e )
{
}
}
public static void main( String[] args )
{
JdbcRowSetTest app = new JdbcRowSetTest ();
}
}
SQLException error:
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
at com.mysql.jdbc.StatementImpl.checkForDml(StatementImpl.java:502)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2224)
at com.sun.rowset.JdbcRowSetImpl.execute(JdbcRowSetImpl.java:582)
at JdbcRowSetTest.(JdbcRowSetTest.java:23)
at JdbcRowSetTest.main(JdbcRowSetTest.java:53)
You can't use a JdbcRowSet to execute insert statements like that. If that is what you want, then you should use a normal Statement or PreparedStatement instead.
The RowSet.setCommand is for queries only:
Sets this RowSet object's command property to the given SQL query. This property is optional when a rowset gets its data from a data source that does not support commands, such as a spreadsheet.
Parameters:
cmd - the SQL query that will be used to get the data for this RowSet object; may be null
If you really want to use a row set, then you can update or insert new rows in the way documented for an updatable ResultSet:
Updating:
to update a column value in the current row. In a scrollable ResultSet
object, the cursor can be moved backwards and forwards, to an absolute
position, or to a position relative to the current row. The following
code fragment updates the NAME column in the fifth row of the
ResultSet object rs and then uses the method updateRow to update the
data source table from which rs was derived.
rs.absolute(5); // moves the cursor to the fifth row of rs
rs.updateString("NAME", "AINSWORTH"); // updates the
// NAME column of row 5 to be AINSWORTH
rs.updateRow(); // updates the row in the data source
For inserting:
to insert column values into the insert row. An updatable ResultSet
object has a special row associated with it that serves as a staging
area for building a row to be inserted. The following code fragment
moves the cursor to the insert row, builds a three-column row, and
inserts it into rs and into the data source table using the method
insertRow.
rs.moveToInsertRow(); // moves cursor to the insert row
rs.updateString(1, "AINSWORTH"); // updates the
// first column of the insert row to be AINSWORTH
rs.updateInt(2,35); // updates the second column to be 35
rs.updateBoolean(3, true); // updates the third column to true
rs.insertRow();
rs.moveToCurrentRow();
Note that the reference implementation of javax.sql.rowset in my experience regularly doesn't work as expected. You might be better off using plain JDBC.
You are missing execute():
To query using "Select" statement and return a JdbcRowSet:
public void createJdbcRowSet(String url, String username, String password, String sql) {
jdbcRs = new JdbcRowSetImpl();
jdbcRs.setCommand(sql);
jdbcRs.setUrl(url);
jdbcRs.setUsername(username);
jdbcRs.setPassword(password);
jdbcRs.execute();
// ...
}
Update:
Once you have the returned JdbcRowSet, you can insert a new row as this example shows:
public void updateJdbcRowSet(String username, String password) {
jdbcRs.moveToInsertRow();
jdbcRs.updateString("USERNAME", "NewUser");
jdbcRs.updateString("PASSWORD", "ENCRYPTED");
jdbcRs.insertRow();
}
public static void main(String[] args) {
try {
RowSetFactory rowset =RowSetProvider.newFactory();
JdbcRowSet jdbcrow=rowset.createJdbcRowSet();
jdbcrow.setUrl(BD_Url);
jdbcrow.setUsername(DB_User);
jdbcrow.setPassword(DB_password);
//this is your database connectivity like uername,password and url and
driver in not imp in mysql 5.1.23 jar file
jdbcrow.setCommand("Select * from Demo");
jdbcrow.execute();
//uppere parts is use to fetch the record from table
System.out.println("--------------------Insert----------");
jdbcrow.moveToInsertRow();
jdbcrow.updateInt("ID", 115);
jdbcrow.updateString("Username","Hitesh");
jdbcrow.updateString("Password","Sir");
jdbcrow.insertRow();
//The down code is used for update the value
System.out.println("=--------------------Update-------------------------");
jdbcrow.absolute(3);// 3rd row
jdbcrow.updateString("Password","Sirs" ); //colname password
jdbcrow.updateRow();
For Delete you can use
System.out.println("=-----------Delete-----------------------------");
while (jdbcrow.next()) {
String id=jdbcrow.getString("Id");
//here i getting ID record from my table
System.out.println("s" +id);
if(id.equals("102")) {
//then i my Specifying that if my table iD is .eqauls to 102 then delete
that record you also used this type to updatetbale
jdbcrow.deleteRow();
System.out.println("gaye");
break;
}
}
//if record delete then preform `enter code here`some operation
//this is used to delete last record from table
System.out.println("=---------------delete-------------------------");
jdbcrow.last();
jdbcrow.deleteRow();
Rather than have to rewrite a class that extends SQLiteOpenHelper every time I want an app with a database component, I'm trying to make a database utility library project. Is this possible?
I call the class DBUtil. It extends SQLiteOpenHelper, overrides onCreate & onUpgrade, and has functions for inserting and selecting rows. It compiles to a jar file.
I include this jar file in another app, DBUtilTests, wherein I create the database, specifying the database name, give it table names and column names for each table. When I get to the part where I insert rows and then do a select to verify the rows are there, nothing is returned.
In the select function in DBUtil, the cursor object is always null for some reason. I've tried creating it both of the following ways:
1:
String tableName="whatever";
//getColumnNamesForTable is a local function that returns the column names
// for a given table in an ArrayList of Strings
final ArrayList<String> columnNamesForTable = getColumnNamesForTable(tableName);
final String[] columns = columnNamesForTable.toArray(new String[columnNamesForTable.size()]);
SQLiteDatabase database = this.getReadableDatabase();
Cursor cursor = database.query(tableName, columns, null, null, "", "", "");
2:
String selectQuery = "SELECT * FROM " + tableName;
Cursor cursor = database.rawQuery(selectQuery, null);
Is there anything wrong in the above code, and if not, is what I'm trying to do possible?
I have a problem with to update a varchar in the sqlite database in java.
when I run this source, than I get a error.
I want String a to update to String b.
This is my source:
public void onClick (View v){
String a = "Test1";
String b = "Test2";
db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
ContentValues values = new ContentValues();
values.put("Level1", b);
db.update("Game", values, a, null);
db.close();
}
And this is my Error:
Error updating Level1=Test2 using update Game SET Level1=? WHERE Test1.
can someone help me?
Thanks!
I'm not 100% sure what you are trying to achieve, however, you added a as a where clause and did not provide any arguments, so consequently you got the SQL statement shown in the error.
From the API:
public int update (String table, ContentValues values,
String whereClause, String[] whereArgs)
This one works ...
db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
ContentValues values = new ContentValues();
values.put("Level1", b);
db.update("Game", values, "Level1=?", new String[] {a} );
db.close();
... if this is the resulting SQL you want to execute:
update Game SET Level1=? WHERE Level1 = 'Test1'
update Game SET Level1=? WHERE Test1.
Where Test1 is.. what? Where is the conditional part of your update statement. It's expecting something like:
update Game SET Level1=? WHERE ColumnName='Test1'
Taken from this website:
If the UPDATE statement does not have a WHERE clause, all rows in the table are modified by the UPDATE. Otherwise, the UPDATE affects only those rows for which the result of evaluating the WHERE clause expression as a boolean expression is true.
A String on it's own is in no way a boolean expression.