reset SQLCipher cipher_page_size cause open database error - sqlcipher

Based on the intro from offical site of SQLCipher, set the cipher_page_size should right after "PRAGMA KEY = 'testkey';". So I create my own DatabaseHelper as following:
public class DatabaseHelper extends SQLiteOpenHelper {
private final static String NEWDBNAME="my.db" ;
public DatabaseHelper(Context context){
super(context, NEWDBNAME, null, 0 ,new SQLiteDatabaseHook(){
#Override
public void postKey(SQLiteDatabase arg0) {
arg0.rawExecSQL("PRAGMA cipher_page_size = 4096");
}
#Override
public void preKey(SQLiteDatabase arg0) {
}});
}
public void onCreate(SQLiteDatabase db) { }
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
public SQLiteDatabase getWritableDatabase()
{
return getWritableDatabase("encodestr");
}
}
The issue is my android application will got an error like : the file is not a db or is encripted...
When I comments: //arg0.rawExecSQL("PRAGMA cipher_page_size = 4096"); , it will run well.
Anybody know this issue?
Thanks.

If the database already exists, unless it was initially created with a cipher_page_size set to 4096, you would need to export the encrypted database with the new setting. Doing so will allow all of the pages to be rewritten to the new block size. An example:
$ ./sqlcipher foo.db
sqlcipher> PRAGMA key = 'foo';
sqlcipher> create table t1(a,b);
sqlcipher> insert into table t1(a,b) values('one for the money', 'two for the show');
sqlcipher> .q
Now foo.db has a default cipher_page_size of 1024, let's export the database with a new cipher_page_size of 4096:
$ ./sqlcipher foo.db
sqlcipher> PRAGMA key = 'foo';
sqlcipher> ATTACH DATABASE 'bar.db' as bar KEY 'foo';
sqlcipher> PRAGMA bar.cipher_page_size = 4096;
sqlcipher> SELECT sqlcipher_export('bar');
sqlcipher> DETACH database bar;
sqlcipher> .q
Now we will need to specify the cipher_page_size when querying the database:
$ ./sqlcipher bar.db
sqlcipher> PRAGMA key = 'foo';
sqlcipher> PRAGMA cipher_page_size = 4096;
sqlcipher> SELECT count(*) from sqlite_master;
count(*)
----------
1

Related

Parsing Pipe delimited file and Storing data into DB using Spring/Java

I have a pipe delimited file (excel xlsx) that I need to parse for certain data. the data is all in column A. the first row has the date, the last row has the row count, and everything in between is the row data. I want to take the first three fields of each row and the date from the header and store it into my H2 Table. There is extra data in my file in each row. I Need help creating code that will parse the file and insert it into my db. I have a Entity and some code written but am stuck now.
My file
20200310|
Mn1223|w01192|windows|extra|extra|extra||
Sd1223|w02390|linux|extra|extra|extra||
2
My table
DROP TABLE IF EXISTS Xy_load ;
CREATE TABLE Xy_load (
account_name VARCHAR(250) NOT NULL,
command_name VARCHAR(250) NOT NULL,
system_name VARCHAR (250) NOT NULL,
CREATE_DT date (8) DEFAULT NULL
);
entity class
public class ZyEntity {
#Column(name="account_name")
private String accountName;
#Column(name="command_name")
private String commandName;
#Column(name="system_name")
private String systemName;
#Column(name="CREATE_DT")
private int createDt;
public ZyEntity(String accountName, String commandName, String systemName){
this.accountName=accountName;
this.commandName=commandName;
this.systemName=systemName;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getCommandName() {
return commandName;
}
public void setCommandName(String commandName) {
this.commandName = commandName;
}
public String getSystemName() {
return systemName;
}
public void setSystemName(String systemName) {
this.systemName = systemName;
}
public int getCreateDt() {
return createDt;
}
public void setCreateDt(int createDt) {
this.createDt = createDt;
}
}
i was able to figure it out with some help
List<DataToInsert> parseData(String filePath) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(filePath));
// remove date and amount
lines.remove(0);
lines.remove(lines.size() - 1);
return lines.stream()
.map(s -> s.split("[|]")).map(val -> new DataToInsert(val[0], val[1], val[2])).collect(Collectors.toList());
}
public void insertZyData(List<ZyEntity> parseData) {
String sql = "INSERT INTO Landing.load (account_name,command_name,system_name)"+
"VALUES (:account_name,:command_name,:system_name)";
for (ZyEntity zyInfo : parseData){
SqlParameterSource source = new MapSqlParameterSource("account_name", zInfo.getAccountName())
.addValue("command_name", zyInfo.getCommandName())
.addValue("system_name", zyInfo.getSystemName());
jdbcTemplate.update(sql, source);
}
}

Trivial create, insert with jdbctemplate

I'm trying to explore the basics of Spring's jdbctemplate. I'm having trouble with a simple example:
public static void main(String[] args) throws Exception {
JdbcDataSource dataSource = new JdbcDataSource();
String url = "jdbc:h2:mem:test";
dataSource.setURL(url);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute("create table something (id int primary key, name varchar(100))");
jdbcTemplate.execute("insert into something (id, name) values (1, 'Brian')");
}
Triggers this:
Caused by: org.h2.jdbc.JdbcSQLException: Table "SOMETHING" not found; SQL statement:
insert into something (id, name) values (1, 'Brian') [42102-177]
If I convert that code to use the raw JDBC api, it works fine:
public static void main(String[] args) throws Exception {
JdbcDataSource dataSource = new JdbcDataSource();
String url = "jdbc:h2:mem:test";
dataSource.setURL(url);
try (Connection dbConnection = dataSource.getConnection()) {
try (Statement statement = dbConnection.createStatement()) {
statement.execute("create table something (id int primary key, name varchar(100))");
statement.execute("insert into something (id, name) values (1, 'Brian')");
try (ResultSet rs = statement.executeQuery("select id, name from something")) {
while (rs.next()) {
System.out.println(String.format("got result. id=%d. name=%s", rs.getInt(1), rs.getString(2)));
}
}
}
}
}
If it matters, my Gradle dependencies:
compile 'org.springframework:spring-jdbc:4.0.6.RELEASE'
compile 'com.h2database:h2:1.4.177'
please try to use update method instead execute.

Insertion operation in SqlCe in windows phone

I am trying to insert some data into mydatabase but getting error like "Can't perform Create, Update, or Delete operations on 'Table(Dic)' because it has no primary key."
My database name is "condrokotha_new.sdf" and it has a table named "dic" which have 2 columns named "english" and "bangla". I made this database in another C# project in vs 2010. Then i used this database into my windowsphone project. I can show data from database but when i try to insert data i am getting error.
Here is my code:
public partial class MainPage : PhoneApplicationPage
{
condrokotha_newContext db = null;
// Constructor
public MainPage()
{
InitializeComponent();
db = new condrokotha_newContext(condrokotha_newContext.ConnectionString);
db.CreateIfNotExists();
db.LogDebug = true;
}
private void fav_Click(object sender, RoutedEventArgs e)
{
add_new_words("cintakhela","ami");
}
private void add_new_words(string e_word,string b_word)
{
using (condrokotha_newContext context = new condrokotha_newContext(condrokotha_newContext.ConnectionString))
{
Dic d = new Dic();
d.English = e_word;
d.Bangla = b_word;
context.Dics.InsertOnSubmit(d);
context.SubmitChanges();
}
}
}
My data context code like these :
public static string ConnectionString = "Data Source=isostore:/condrokotha_new.sdf";
public static string ConnectionStringReadOnly = "Data Source=appdata:/condrokotha_new.sdf;File Mode=Read Only;";
public static string FileName = "condrokotha_new.sdf";
public condrokotha_newContext(string connectionString) : base(connectionString)
{
OnCreated();
}
#region Extensibility Method Definitions
partial void OnCreated();
#endregion
public System.Data.Linq.Table<Dic> Dics
{
get
{
return this.GetTable<Dic>();
}
}
}
[global::System.Data.Linq.Mapping.TableAttribute(Name="dic")]
public partial class Dic
{
private string _English;
private string _Bangla;
public Dic()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="english", Storage="_English", DbType="NVarChar(1000)")]
public string English
{
get
{
return this._English;
}
set
{
if ((this._English != value))
{
this._English = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="bangla", Storage="_Bangla", DbType="NText", UpdateCheck=UpdateCheck.Never)]
public string Bangla
{
get
{
return this._Bangla;
}
set
{
if ((this._Bangla != value))
{
this._Bangla = value;
}
}
}
}
`
How can i insert my data into my database??
Is there anyone who can help in this??
For example you have this
SampleDataContextDataContext db = new SampleDataContextDataContext();
Employee emp = new Employee() {
FirstName = "Experts",
Lastname = "Comment",
Address = "rs.emenu#gmail.com"
}
db.Employees.InsertOnSubmit(emp);
db.SubmitChanges();
The above code will give you same error when u try to insert a new row. The reason is that LINQ does not provide the facility to insert data into a table without a primary key. At this point you have two options.
1.Create a store procedure and call it from LINQ.
SampleDataContextDataContext db = new SampleDataContextDataContext();
db.InsertEmployeeData("Experts","Comment", "rs.emenu#gmail.com");
Here InsertEmployeeData is a a stored procedure, and called it from the code.
2.Create an insert statement and execute using LINQ.
SampleDataContextDataContext db = new SampleDataContextDataContext();
string insertStatement = "Insert into Employee values('Experts', 'Comment','rs.emenu#gmail.com')";
db.ExecuteQuery<Employee>(insertStatement);
Here insert query is normal sql query and executed using the the LINQ ExecuteQuery method.

Added DataColumns not being saving in Access Database

I would like to write code to add a DataColumn to a DataTable, but when I save the DataTable, it does not include the new DataColumn.
It saves any new DataRows I add, but not the DataColumns.
Can somebody please tell me what I am doing wrong?
public partial class Form1 : Form
{
MyDatabase DB;
DataTable Products;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DB = new MyDatabase();
DB.Open(#"C:\Users\Grant\Documents\Database.accdb");
Products = DB.GetTable("Products");
AddColumn();
AddRow();
DB.Save(Products);
}
private void AddColumn()
{
DataColumn Column = new DataColumn();
Column.DataType = Type.GetType("System.String");
Column.ColumnName = "TestColumn";
Products.Columns.Add(Column);
}
private void AddRow()
{
DataRow Row;
Row = Products.Rows.Add(1, "B", "C");
}
}
class MyDatabase
{
// The following program has to be installed on the computer
// http://www.microsoft.com/downloads/en/details.aspx?familyid=7554F536-8C28-4598-9B72-EF94E038C891&displaylang=en
private String provider = "Microsoft.ACE.OLEDB.12.0";
private String source;
private OleDbConnection connection;
private String connectionString;
private DataSet dataSet = new DataSet();
private OleDbDataAdapter adapter;
private OleDbCommandBuilder commandBuilder;
public String Provider
{
get { return provider; }
set { provider = value; }
}
public String Source
{
get { return Source; }
set { source = value; }
}
public void Open(String Filename)
{
connectionString = #"Provider=" + provider + #";Data Source=" + Filename;
connection = new OleDbConnection(connectionString);
connection.Open();
adapter = new OleDbDataAdapter();
}
public void BuildStrings()
{
commandBuilder = new OleDbCommandBuilder(adapter);
adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
adapter.InsertCommand = commandBuilder.GetInsertCommand();
adapter.DeleteCommand = commandBuilder.GetDeleteCommand();
}
public DataTable GetTable(String TableName)
{
adapter.SelectCommand = new OleDbCommand("SELECT * From " + TableName, connection);
BuildStrings();
adapter.Fill(dataSet, TableName);
return dataSet.Tables[TableName];
}
public void Save(DataTable Table)
{
adapter.Update(Table);
adapter.Update(dataSet, "Products");
}
}
Got an answer from a different forum.
You can not add new column/field to database table using dataset or datatable you might need to use "ALTER TABLE" with ADO.NET commands. Check below links
How Can I Insert New Column Into A Database Table Using SqlDataAdapter and DataTable?[^]
adding a column to a SQL table in VB using ADO.NET commands[^]

How to access this stored Procedure from JDBC Callablestatement?

How to access this stored Procedure from JDBC Callablestatement ??
public class TestOCIApp {
public static void main(String args[]) throws ClassNotFoundException,
SQLException {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:orcle", "scott", "tiger");
CallableStatement cs = conn.prepareCall("{call test(?,?)}");
cs.setInt(1, 10);
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
ResultSet rs = (ResultSet)cs.getObject(2);
while(rs.next())
{
System.out.println(rs.getString(2));
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am getting Exception as
java.sql.SQLException: Invalid column index
* at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)*
* at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:222)*
* at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:285)*
* at oracle.jdbc.driver.OracleStatement.prepare_for_new_get(OracleStatement.java:2804)*
* at oracle.jdbc.driver.OracleStatement.getObjectValue(OracleStatement.java:4983)*
* at oracle.jdbc.driver.OracleStatement.getObjectValue(OracleStatement.java:4964)*
* at oracle.jdbc.driver.OracleCallableStatement.getObject(OracleCallableStatement.java:586)*
* at TestOCIApp.main(TestOCIApp.java:23)*
create or replace procedure test( p_deptno IN number
, p_cursor OUT SYS_REFCURSOR)
is
begin
open p_cursor FOR
select *
from emp
where deptno = p_deptno;
end test;
/
When dealign with oracle cursors,The CallableStatement object is cast to OracleCallableStatement to use the getCursor method, which is an Oracle extension to the standard JDBC application programming interface (API), and returns the REF CURSOR into a ResultSet object.
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
cursor = ((OracleCallableStatement)cstmt).getCursor(1);
while (cursor.next ()){
System.out.println (cursor.getString(1));
}
But this will couple your code to oracle database [:(]

Resources