Why table is not created in SQLite Android studio 3.1.4 or 3.2.1 - android-sqlite

Why table is not created in SQLite Android studio 3.1.4 or 3.2.1
I use this code at home on Android studio 3.1 works perfectly but in 3.1.4 and 3.2.1 which I use at school it make the database but not the table.
I have used logcat to print the query and paste it into db browser and it works perfectly and creates the table. I have done a number of Log.d in the onCreate() method to confirm the code is arriving in that method and it is arriving in the method.
public class SQLCon extends SQLiteOpenHelper
{
public static final String DBNAME = "unidb.db";
public static int VER = 1;
private SQLiteDatabase db;
final String CREATEUSERTABLE = "CREATE Table IF NOT EXISTS "+
ContractSQL.User.TABLE_NAME+"( "+
ContractSQL.User.ID+" INTEGER PRIMARY KEY autoincrement,"+
ContractSQL.User.FN+" varchar(45),"+
ContractSQL.User.SN+" varchar(45),"+
ContractSQL.User.EM+" varchar(45),"+
ContractSQL.User.GROUP+" varchar(45),"+
ContractSQL.User.PW+ " varchar(45));";
public SQLCon(Context context) {
super(context, DBNAME, null, VER);
this.getWritableDatabase();
//onCreate(this.getWritableDatabase());
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d("CREATEUSERTABLETAG", CREATEUSERTABLE);
db.execSQL(CREATEUSERTABLE);
//this.getWritableDatabase().execSQL(CREATEUSERTABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Contract Class:
public final class ContractSQL
{
private ContractSQL(){}
public static class User
{
public static final String TABLE_NAME = "_user_";
public static final String ID = "_id_";
public static final String FN = "_fn_";
public static final String SN = "_sn_";
public static final String GROUP = "_group_";
public static final String PW = "_pw_";
public static final String EM = "_em_";
}
}

Copying the above code into SQLCon.java and ContractSQL.java respectively and then utilising the code from an activity using :-
public class MainActivity extends AppCompatActivity {
AdminSQLiteOpenHelper mASQLiteHlpr;
SQLCon mSQLcon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSQLcon = new SQLCon(this);
Cursor csr = mSQLcon.getWritableDatabase().query("sqlite_master",null,null,null,null,null,null);
while (csr.moveToNext()) {
Log.d("DBINFO", "Found Item " + csr.getString(csr.getColumnIndex("name")));
}
csr.close();
}
}
Works fine and produces the following in the log :-
10-25 19:40:37.311 1164-1164/axtest.axtest D/CREATEUSERTABLETAG: CREATE Table IF NOT EXISTS _user_( _id_ INTEGER PRIMARY KEY autoincrement,_fn_ varchar(45),_sn_ varchar(45),_em_ varchar(45),_group_ varchar(45),_pw_ varchar(45));
10-25 19:40:37.311 1164-1164/axtest.axtest D/DBINFO: Found Item android_metadata
10-25 19:40:37.311 1164-1164/axtest.axtest D/DBINFO: Found Item _user_
10-25 19:40:37.311 1164-1164/axtest.axtest D/DBINFO: Found Item sqlite_sequence
android_metadata being a table created by the SQLite code available with android (it is used for the locale).
sqlite_sequence is created because you have coded AUTOINCREMENT. It contains the highest rowid used to date (unless modified).
coding ?? INTEGER PRIMARY KEY (with or without AUTOINCREMENT)makes the column ?? (id in your case) an alias of the special column rowid. rowid is a unqiue signed 64 bit integer. It will initially be 1 and will then generally increment by 1 (although there is no guarantee that it will).
AUTOINCREMENT has overheads and only introduces a constraint that the rowid must always be larger. It is rarely required and it is recommended to not use AUTOINCREMENT.SQLite Autoincrement
As such, it would appear that you are either not checking that the table exists using a sound method (an example of a sound method is included in the code above) or that there are some external constraints due to the different environments.
Adopting the above code that queries the sqlite_master table, would show if the table is being created.

Related

want to delete database file in my app. .tried with a program, that did not work

I am trying to delete database table either programmatically or manually.
I created my own app which is under development.
My app is named SWULJ CT Conductor
But I do not find it under android/data/data folder with any com.xxx.xxx name format
code:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "BusDetails.db";
public static final String TABLE_NAME = "bus_details_table";
public static final String COL_1 = "ID";
public static final String COL_2 = "NUMBER";
public static final String COL_3 = "ROUTE";
public static final String COL_4 = "CITY";
public static final String COL_5 = "STATUS";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String myPath = TABLE_NAME + DATABASE_NAME;
SQLiteDatabase.deleteDatabase(new File(myPath));
db.execSQL("create table " + TABLE_NAME +" (ID INTEGER PRIMARY KEY AUTOINCREMENT,NUMBER TEXT,ROUTE TEXT,CITY TEXT,STATUS INTEGER)");
}
It is the partial code for the databasehelper class
It is called from Activity like this:
public class GenerateQrCodeActivity extends AppCompatActivity {
ImageButton imgButtonGenerateBulk;
ImageButton imgButtonGenerateSingle;
DatabaseHelper myDb;
EditText edit;
boolean flag = false;
String data_bus_number=null;
int ID_bus_number = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_generate_qr_code);
myDb = new DatabaseHelper(this);
imgButtonGenerateBulk =(ImageButton)findViewById(R.id.imageButtonGenerateBulk);
imgButtonGenerateSingle =(ImageButton)findViewById(R.id.imageButtonGenerateSingle);
edit = (EditText) findViewById(R.id.bus_number);
.....
.....
I placed lines
String myPath = TABLE_NAME + DATABASE_NAME;
SQLiteDatabase.deleteDatabase(new File(myPath));
But the old data from the database shows up. It is not deleted. Why? how to fix?
done using the function->
public void deleteDatabase() {
// Are you sure? (y/n)
final SQLiteDatabase db = this.getWritableDatabase();
final File dbFile = new File(db.getPath());
db.close();
Toast.makeText(cntxt, "db deleted", Toast.LENGTH_SHORT).show();
edit.setText("db deleted");
if (dbFile.exists()) {
SQLiteDatabase.deleteDatabase(dbFile);
}
//mOpenHelper = new DatabaseHelper(getContext());
}

Can I write my own Queries in a Spring boot web app?

I'm making my first springboot web app, and trying to display some information from a postgresql server. When trying to get some information out of the database, it returns an empty list. By what I can see in the console, it tries to query with the wrong parameters.
In my DB I have a table with three fields: "userId", "firstName", and "surName".
From what i can understand, Hibernate tries to query with the parameters "users0_.user_id", "users0_user_id", "users0_.sur_name".
To fix this i want to write my own queries or fix the current one. How do I do this?
As you can see I have checked the results of the query with some System.Out.print statements.
The first one returned a list.size() of 0,
and the second one returned a value of null.
Console displaying what I think is the query info
This is the function in my UserController class used to display the users' info.
#RequestMapping("/users")
public String getUsers(Model model) {
List <users>users = (List<users>) userServ.listAll();
System.out.print("THE SIZE WITH STRING CONCATINATION IS: " + users.size());
model.addAttribute("users", users);
System.out.print("THE NAME OF USER WITH INDEX =2 IS: " + userServ.getById(2).getFirstName());
return "showUsers";
}
The entity/domain-class for a user:
#Entity
#Table(name="users")
public class users implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
private String firstName;
private String surName;
private long getId() { return userId; }
public void setId(long id) {this.userId = id;}
public String getFirstName() { return firstName; }
public String getSurName() { return surName; }
public void setSurname(String surName) {this.surName = surName; }
}
This is the interface of the repository used to retrieve users from the DB:
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import com.svein.models.users;
public interface UserRepository extends CrudRepository<users, Long> {
}
This is the service class for the users:
#Service
public class UserServiceImp implements userService{
#Autowired
private UserRepository userRepo;
#Override
public List<users> listAll() {
List<users> users = new ArrayList<>();
userRepo.findAll().forEach(users::add);
return users;
}
#Override
public users getById(long id) {
return userRepo.findById(id).orElseGet(users::new);
}
#Override
public users saveOrUpdate(users user) {
userRepo.save(user);
return null;
}
#Override
public void delete(Long id) {
userRepo.deleteById(id);
}
}
I was hoping to adjust or replace the current query, but maybe there is something alse wrong with the code. As I said, I'm quite new to this, but thought it was weird that i had not written a single line of SQL, and in a different project THAT showed signs of retrieving the right information(from a different DB). How does the class know what to query for?
You need to add an #Query annotation on top of query function you want to write in your UserRepository class.
For e.g
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.CrudRepository;
import com.svein.models.users;
public interface UserRepository extends CrudRepository<users, Long> {
#Query("Select * from users")
List<users> findAllUsers();
}
Alternatively in your UserServiceImpl, userRepo.findAll() should work.You do not need to loop through each user and return it to list. You should simply return userRepo.findAll().
Following url would give you more idea about how to write your own query.
https://www.baeldung.com/spring-data-jpa-query

Wicket 7 - Select, SelectOptions and pre-set

Im using Select instead of DropDownChoice to use OPTGROUP.
Select<Role> roleInput = new Select<Role>("role", new PropertyModel<Role>(this,"selectedRole"));
The two list of Role are:
SelectOptions<Role> fedOptions = new SelectOptions<Role>("federazione",federationRoleList,new RoleRenderer());
SelectOptions<Role> eOptions = new SelectOptions<Role>("enti",eRoleList,new RoleRenderer());
Its working well when submitting and also applying a AjaxFormComponentUpdatingBehavior on roleInput, I have my PropertyModel dynamically modified.
Unfortunally I have a problem with pre-set.
I tried to set selectedRole with a specific Role but the Select always start with the first element of the first list.
DropDownChoice works perfectly pre-setting the model but not Select.
I've tried with
roleInput.setModelObject(selectedRole);
but its not working.
I thinks the problem is with this component that has to manage two or more Repeaters instead of a single list.
Any clue?
Thanks
EDIT:
Implementation of RoleRenderer
public class RoleRenderer implements IChoiceRenderer<Role>,Serializable{
private static final long serialVersionUID = 1L;
#Override
public Object getDisplayValue(Role object) {
return object.getName();
}
#Override
public String getIdValue(Role object, int index) {
return object.getId().toString();
}
#Override
public Role getObject(String id, IModel<? extends List<? extends Role>> choices) {
return getObjectFromId(id);
}
public Role getObjectFromId(String id){
return null;
};
}
NOTE: getObjectFromId require access to Manager so will be overrided outside.
Put a breakpoint at org.apache.wicket.extensions.markup.html.form.select.SelectOption#onComponentTag() and see what is returned by select.isSelected(this) for the SelectionOption that matches the default model (object).
It might be that your #equals() implementation is not correct.

Pass current step output to next step and write to flatfile

I need to prepare two set of List and write them into FlatFile. The first set will be only simple retrieving from SQL and before write into FlatFile will do some string formatting. Another set of data slightly complex, first I need to get data from some table and insert into a temp table. The data will grab from this temp table and similarly need to perform some string formatting and also updating the temp file. Finally, both set data write into FlatFile.
Come into Spring Batch, I will have 3 steps.
First Step
First Reader read from DB
First Processor string formatting
First Writer write into file
Second Step
BeforeRead Retrieve and Insert to Temp table
Second Reader read from temp table
Second Processor string formatting and update temp table status
Second Writer write into file
Third Step
MUltiResourceItemReader read two files
Write into Final File
Tasklet
Delete both file and purge the temp table.
My question now is for first and second step if I don't write into file, possible to pass the data into third step?
Taking in account what Hansjoerg Wingeier said, below are custom implementations of ListItemWriter and ListItemReader which lets you define a name property. This property is used as a key to store the list in the JobExecutionContext.
The reader :
public class CustomListItemReader<T> implements ItemReader<T>, StepExecutionListener {
private String name;
private List<T> list;
#Override
public T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if (list != null && !list.isEmpty()) {
return list.remove(0);
}
return null;
}
#Override
public void beforeStep(StepExecution stepExecution) {
list = (List<T>) stepExecution.getJobExecution().getExecutionContext().get(name);
}
#Override
public ExitStatus afterStep(StepExecution stepExecution) {
return null;
}
public void setName(String name) {
this.name = name;
}
}
The writer :
public class CustomListItemWriter<T> implements ItemWriter<T>, StepExecutionListener {
private String name;
private List<T> list = new ArrayList<T>();
#Override
public void write(List<? extends T> items) throws Exception {
for (T item : items) {
list.add(item);
}
}
#Override
public void beforeStep(StepExecution stepExecution) {}
#Override
public ExitStatus afterStep(StepExecution stepExecution) {
stepExecution.getJobExecution().getExecutionContext().put(name, list);
return null;
}
public void setName(String name) {
this.name = name;
}
}
Normally, you don't want to do that.
If you just have a couple of hundred entries, it would work. You could, for instance, write a special class, that implements the reader and writer interface. When writing, just store the data in a list, when reading, read the entries from the list. Just instantiate it as a bean and use it in both steps (1 and 2) as your writer. by simply make the write method synchronized, it would even work when step 1 and 2 are executed in parallel.
But the problem is, that this solution doesn't scale with the amount of your input data. the more data you read, the more memory you need.
This is one of the key concepts of batch-processing: having a constant memory usage regardless of the amount of data that has to be processed.

Overriding Getters and Setters in tinkerpop Frames annotated model

I'm working on a new piece of software and I'd like the values in the database to be encrypted. We are using OrientDB and are trying to implement the project using the tinkerpop libraries. Here I'm stuck a little bit.
For one function, I need to pull a list of all vertices of a type and return them. I have my annotated interface for the person object, and I added methods to encrypt and decrypt necessary fields right now. But when I decrypt them, it persists the decrypted values back to the database.
Is there a way to either override the getters and setters to handle the encryption/decryption at that point or do I need to detach the models from the db before performing my decryption?
Here's my code for my interface:
public interface iPerson {
#Property("firstName")
public void setFirstName(String firstName);
#Property("firstName")
public String getFirstName();
#Property("lastName")
public String getLastName();
#Property("lastName")
public void setLastName(String lastName);
#Property("id")
public String getId();
#Property("id")
public void setId(String id);
#Property("dateOfBirth")
public String getDateOfBirth();
#Property("dateOfBirth")
public void setDateOfBirth(String dateOfBirth);
#JavaHandler
public void encryptFields() throws Exception;
#JavaHandler
public void decryptFields() throws Exception;
public abstract class Impl implements JavaHandlerContext<Vertex>, iPerson {
#Initializer
public void init() {
//This will be called when a new framed element is added to the graph.
setFirstName("");
setLastName("");
setDateOfBirth("01-01-1900");
setPK_Person("-1");
}
/**
* shortcut method to make the class encrypt all of the fields that should be encrypted for data storage
* #throws Exception
*/
public void encryptFields() throws Exception {
setLastName(Crypto.encryptHex(getLastName()));
setFirstName(Crypto.encryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.encryptHex(getDateOfBirth()));
}
}
/**
* shortcut method to make the class decrypt all of the fields that should be decrypted for data display and return
* #throws Exception
*/
public void decryptFields() throws Exception {
setLastName(Crypto.decryptHex(getLastName()));
setFirstName(Crypto.decryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.decryptHex(getDateOfBirth()));
}
}
}
}
(I assume) Data is persisted to the database when a Vertex's property is set. If you want to store encrypted values in the database, then you need to ensure the value is encrypted when the property is set.
If you want to override the default behaviour of the #Property getter/setter methods (so that you can add en/decryption), I'd recommend using a custom handler (e.g. #JavaHandler).
For example:
IPerson
#JavaHandlerClass(Person.class)
public interface IPerson extends VertexFrame {
#JavaHandler
public void setFirstName(String firstName);
#JavaHandler
public String getFirstName();
}
Person
abstract class Person implements JavaHandlerContext<Vertex>, IPerson {
#Override
void setFirstName(String firstName) {
asVertex().setProperty('firstName', encrypt(firstName))
}
#Override
String getFirstName() {
return decrypt(asVertex().getProperty('firstName'))
}
static String encrypt(String plain){
return plain.toUpperCase(); // <- your own implementation here
}
static String decrypt(Object encrypted){
return encrypted.toString().toLowerCase(); // <- your own implementation here
}
}
Usage example (Groovy)
// setup
IPerson nickg = framedGraph.addVertex('PID1', IPerson)
IPerson jspriggs = framedGraph.addVertex('PID2', IPerson)
nickg.setFirstName('nickg')
jspriggs.setFirstName('jspriggs')
// re-retrieve from Frame vertices sometime later...
IPerson nickg2 = framedGraph.getVertex(nickg.asVertex().id, IPerson)
IPerson jspriggs2 = framedGraph.getVertex(jspriggs.asVertex().id, IPerson)
// check encrypted values (these are stored in the DB)...
assert nickg2.asVertex().getProperty('firstName') == 'NICKG'
assert jspriggs2.asVertex().getProperty('firstName') == 'JSPRIGGS'
// check decrypted getters...
assert nickg2.getFirstName() == 'nickg'
assert jspriggs2.getFirstName() == 'jspriggs'
If using Groovy, you could intercept calls to these methods programatically (which would be nice because you could keep using #Property annotations).
I'm not sure if there's a Tinkerpop solution to intercepting these calls, other than writing your own custom handler (maybe try extending the JavaHandlerModule?).
Thanks for the comment, and I should have gotten back to respond to this sooner, but I recently found a better answer to my problem. I was looking for a way to make the encrypt/decrypt happen without overhead and without developers really noticing it happens.
The better way to tackle this issue was actually to write hooks for before insert/update and after read to handle it just at the database layer. I was able to write it in java, package a jar file for it and install it on our orientDB instance, picked up pretty flawlessly and helped us to encrypt the necessary fields without noticing any speed decreases.