Database that already exists is replaced by calling the method CreateTable <> in SQLite for Windows 8, erasing all the lines and creating a new table. How can I solve? following code to analyze:
using(var db = new SQLite.SQLiteConnection(App.DBPath))
{
db.CreateTable<ListasEntid>();
if (db.ExecuteScalar<int>("select count(1) from ListasEntid")==0)
{
db.RunInTransaction(() =>
{
db.Insert(new ListasEntid() { Nome = "Lista", Eletros = "Teste" });
});
}
}
Not sure what language you are using, but if you can execute raw SQL then you can use the following syntax:
CREATE TABLE IF NOT EXISTS ListasEntid (nome text, eletros text);
This ensures that table ListasEntid exists without nuking any of your previous data.
Thank you for the attention, but the problem was not specifically CreateTable method, but in the application configuration in the application properties, Debug tab, in option start the box was marked, "Unistall and then re-install my packege", erasing all files always initializing the debug.
Related
During development structures and requirements change. Key and index settings need to be changed, that might break incremental table update. So my solution so far is to delete the table and recreate it from the cloudformation stack.
But how to solve this problem with a production deployment? Is it possible to automate dynamodb deployment as follows?
Create new table
Migrate data from old table to new table
Delete old table
Yes, it is perfectly possible to automate such a deployment structure. As long as you have code to create a table, it should be fairly straightforward to get all of the data from an old table, change the data, and then upload it all to a new table without any drops in up-time. If you write what language you would like to do such a thing in I can help a bit more.
I've done this before and I've added below a small generified code-sample on how you could do this in Java.
Java method for creating a table given the class of the object type stored in dynamo:
/**
* Creates a single table with its appropriate configuration (CreateTableRequest)
*/
public void createTable(Class tableClass) {
DynamoDBMapper mapper = createMapper(); // you'll need your own function to do this.
ProvisionedThroughput pt = new ProvisionedThroughput(1L, 1L);
CreateTableRequest ctr = mapper.generateCreateTableRequest(tableClass);
ctr.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
// Provision throughput and configure projection for secondary indices.
if (ctr.getGlobalSecondaryIndexes() != null) {
for (GlobalSecondaryIndex idx : ctr.getGlobalSecondaryIndexes()) {
if (idx != null) {
idx.withProvisionedThroughput(pt).withProjection(new Projection().withProjectionType("ALL"));
}
}
}
TableUtils.createTableIfNotExists(client, ctr);
}
Java method to delete table:
private static void deleteTable(String tableName) {
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable(tableName);
try {
System.out.println("Issuing DeleteTable request for " + tableName);
table.delete();
System.out.println("Waiting for " + tableName + " to be deleted...this may take a while...");
table.waitForDelete();
}
catch (Exception e) {
System.err.println("DeleteTable request failed for " + tableName);
System.err.println(e.getMessage());
}
}
I would scan the whole table and plop all of the content into a List and then map through that list, converting the objects into your new type, and then create a new table of that type but with a different name, push all of your new objects, and then delete the old table after switching any references you might have of the old table to the new one. Unfortunately this does mean that everything consuming your tables are going to need to be able to switch between your two staging tables.
I have a very unusual problem.
I'm trying to create a simple database (6 tables, 4 of which only have 2 columns).
I'm using an in-house database library which I've used in a previous project, and it does work.
However with my current project there are occasional bugs. Basically the database isn't created correctly. It is added to the sdcard but when I access it I get a DatabaseException.
When I access the device from the desktop manager and try to open the database (with SQLite Database Browser v2.0b1) I get "File is not a SQLite 3 database".
UPDATE
I found that this happens when I delete the database manually off the sdcard.
Since there's no way to stop a user doing that, is there anything I can do to handle it?
CODE
public static boolean initialize()
{
boolean memory_card_available = ApplicationInterface.isSDCardIn();
String application_name = ApplicationInterface.getApplicationName();
if (memory_card_available == true)
{
file_path = "file:///SDCard/" + application_name + ".db";
}
else
{
file_path = "file:///store/" + application_name + ".db";
}
try
{
uri = URI.create(file_path);
FileClass.hideFile(file_path);
} catch (MalformedURIException mue)
{
}
return create(uri);
}
private static boolean create(URI db_file)
{
boolean response = false;
try
{
db = DatabaseFactory.create(db_file);
db.close();
response = true;
} catch (Exception e)
{
}
return response;
}
My only suggestion is keep a default database in your assets - if there is a problem with the one on the SD Card, attempt to recreate it by copying the default one.
Not a very good answer I expect.
Since it looks like your problem is that the user is deleting your database, just make sure to catch exceptions when you open it (or access it ... wherever you're getting the exception):
try {
URI uri = URI.create("file:///SDCard/Databases/database1.db");
sqliteDB = DatabaseFactory.open(myURI);
Statement st = sqliteDB.createStatement( "CREATE TABLE 'Employee' ( " +
"'Name' TEXT, " +
"'Age' INTEGER )" );
st.prepare();
st.execute();
} catch ( DatabaseException e ) {
System.out.println( e.getMessage() );
// TODO: decide if you want to create a new database here, or
// alert the user if the SDCard is not available
}
Note that even though it's probably unusual for a user to delete a private file that your app creates, it's perfectly normal for the SDCard to be unavailable because the device is connected to a PC via USB. So, you really should always be testing for this condition (file open error).
See this answer regarding checking for SDCard availability.
Also, read this about SQLite db storage locations, and make sure to review this answer by Michael Donohue about eMMC storage.
Update: SQLite Corruption
See this link describing the many ways SQLite databases can be corrupted. It definitely sounded to me like maybe the .db file was deleted, but not the journal / wal file. If that was it, you could try deleting database1* programmatically before you create database1.db. But, your comments seem to suggest that it was something else. Perhaps you could look into the file locking failure modes, too.
If you are desperate, you might try changing your code to use a different name (e.g. database2, database3) each time you create a new db, to make sure you're not getting artifacts from the previous db.
I am doing a project in wicket
How to solve the problem.
I came across such a message:
WicketMessage: Can't instantiate page using constructor public itucs.blg361.g03.HomePage()
Root cause:
java.lang.UnsupportedOperationException: [SQLITE_BUSY] The database file is locked (database is locked)
at itucs.blg361.g03.CategoryEvents.CategoryEventCollection.getCategoryEvents(CategoryEventCollection.java:41)
public List<CategoryEvent> getCategoryEvents() {
List<CategoryEvent> categoryEvents = new
LinkedList<CategoryEvent>();
try {
String query = "SELECT id, name, group_id"
+ " FROM event_category";
Statement statement = this.db.createStatement();
ResultSet result = statement.executeQuery(query);
while (result.next()) {
int id = result.getInt("id");
String name = result.getString("name");
int group_id = result.getInt("group_id");
categoryEvents.add(new CategoryEvent(id, name, group_id));
}
} catch (SQLException ex) {
throw new UnsupportedOperationException(ex.getMessage());
}
return categoryEvents;
}
at itucs.blg361.g03.HomePage.(HomePage.java:71)
categories = categoryCollection.getCategoryEvents();
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
Sqlite allows only one writer to the whole database at a time and, unless you selected "WAL" journal mode, no reader while writing. Moreover unless you explicitly ask it to wait, it simply returns the SQLITE_BUSY status for any attempt to access the database while conflicting operation is running.
You can tell sqlite to wait for the database to become available for a specified amount of time. The C-level API is sqlite3_busy_timeout; I never used sqlite from Java though, so I don't know where to find it there.
(...) tell sqlite to wait for the database to become available for specified amount of time.
In order to do it from Java, run the following statement just like a simple SQL statement:
pragma busy_timeout=30000; -- Busy timeout set to 30000 milliseconds
I am using ASP.NET MVC2 in Visual Studio 2008. I believe the SQL Server is 2005.
I have two tables: EquipmentInventory and EquipmentRequested
EquipmentInventory has a primary key
of sCode
EquipmentRequested has a
foreign key called sCode based upon
sCode in EquipmentInventory.
I am trying the following code (lots of non-relevent code removed):
try
{
EChODatabaseConnection myDB = new EChODatabaseConnection();
//this section of code works fine. The data shows up in the database as expected
foreach (var equip in oldData.RequestList)
{
if (equip.iCount > 0)
{
dbEquipmentInventory dumbEquip = new dbEquipmentInventory();
dumbEquip.sCode = equip.sCodePrefix + newRequest.iRequestID + oldData.sRequestor;
myDB.AddTodbEquipmentInventorySet(dumbEquip);
}
}
myDB.SaveChanges(); //save this out immediately so we can add in new requests
//this code runs fine
foreach (var equip in oldData.RequestList)
{
if (equip.iCount > 0)
{
dbEquipmentRequested reqEquip = new dbEquipmentRequested();
reqEquip.sCode = equip.sCodePrefix + newRequest.iRequestID + oldData.sRequestor;
myDB.AddTodbEquipmentRequestedSet(reqEquip);
}
}
//but when I try to save the above result, I get an error
myDB.SaveChanges();
oldData is passed into the function. newRequest is the result of adding to a "non-related" table. newRequest.iRequestID does have a value.
In looking at the reqEquip is the watch window, I do notice that EquipInventory is null.
The error message I receive is:
"Entities in 'EChODatabaseConnection.dbEquipmentRequestedSet' participate in the 'FK_EquipmentRequested_EquipmentInventory_sCode' relationship. 0 related 'EquipmentInventory' were found. 1 'EquipmentInventory' is expected."
Obviously I'm doing something wrong but thus far, I can not seem to find where I am having a problem.
Anyone have some hints on how to properly insert a record into a table that has a foreign key reference?
UPDATE:
I am using the Data Entity Framework.
UPDATE:
Thanks to Rob's answer, I was able to figure out my error.
As Rob mentioned, I needed to set my reference for the foreign key.
My coding result looks like:
foreach (var equip in oldData.RequestList)
{
if (equip.iCount > 0)
{
dbEquipmentInventory dumbEquip = new dbEquipmentInventory();
dumbEquip.sCode = equip.sCodePrefix + newRequest.iRequestID + oldData.sRequestor;
myDB.AddTodbEquipmentInventorySet(dumbEquip);
//add in our actual request items
dbEquipmentRequested reqEquip = new dbEquipmentRequested();
reqEquip.EquipmentInventory = dumbEquip;
myDB.AddTodbEquipmentRequestedSet(reqEquip);
}
}
myDB.SaveChanges();
Does anyone see a better method for doing this?
What are you using as an ORM? I believe that regardless of which one you're using, you could use the foreign key handling of most ORMs to handle this for you. For example, you make a new dumbEquip, don't do the immediate save. Do your dbEquipmentRequested reqEquip = new dbEquipmentRequested(); and add the data to it and then say dumbEquip.dbEquipmentRequested.Add(reqEquip). Then save the record and the ORM should save the records in the correct order required for the FK and even enter the FK ID into the reqEquip record.
I am using SQLite for Windows Phone 7 (http://sqlitewindowsphone.codeplex.com/) and I have done every steps from this tutorial (http://dotnetslackers.com/articles/silverlight/Windows-Phone-7-Native-Database-Programming-via-Sqlite-Client-for-Windows-Phone.aspx)
Then I try to make some simple application with basic features like select and delete. App is working properly till I want to make one of this operations. After I click select or delete, compiler shows me errors that he is unable to open database file...
I have no idea why?
I used the same Sqlite client, and had the same problem. This problem occurs because the sqlite try to create file in IsolatedFileStorage "DatabaseName.sqlite-journal" and it does not have enough permissions for that. I solved the problem, so that created "DatabaseName.sqlite-journal" before copying database to IsolatedFileStorage. Here's my method that did it:
private void CopyFromContentToStorage(String assemblyName, String dbName)
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string uri = dbName + "-journal";
store.CreateFile(uri);
using (Stream input = Application.GetResourceStream(new Uri("/" + assemblyName + ";component/" + dbName,UriKind.Relative)).Stream)
{
IsolatedStorageFileStream dest = new IsolatedStorageFileStream(dbName, FileMode.OpenOrCreate, FileAccess.Write, store);
input.Position = 0;
CopyStream(input, dest);
dest.Flush();
dest.Close();
dest.Dispose();
}
}
it helped me, and worked well.
hope this will help you
Are you sure the file exists?
You can check like that:
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
exists = store.FileExists(DbfileName);
}