Sugar ORM - Difference between save() and update() - android-sqlite

What is the difference between save() and update() in sugar ORM?
By referring to this Sugar ORM in Android: update a saved object in SQLite
save and update are giving same result?
I want to update the existing record if exist how to do that?
here I want to do something like:
long count = Lead.count(Lead.class);
if (count > 0) {
List<Lead> leads = Lead.find(Lead.class, "lead_id = ?", leadItem.leadId);
if (leads == null) { // save leadItem
Lead.save(lead);
logFile.writeLog("Home Activity: Lead saved in local DB. Lead Id is: " + leadItem.leadId + " leadItem Name: " + leadItem.name);
Log.d("Lead saved: ", leadItem.toString());
} else { // update leadItem
Lead.update(lead);
logFile.writeLog("Home Activity: Lead updated in local DB. Lead Id is: " + leadItem.leadId + " leadItem Name: " + leadItem.name);
Log.d("Lead updated: ", leadItem.toString());
}
}
Here when I call update it is also updating the another record which I saved with different ID and adding as new record rather update.

Related

Bukkit - Displaying null when getting a string from the config file

So I've been working on a custom feature for my minecraft server, one of the things that I need to do is get an integer from the config file that is specific to each player to display how many Packages(keys) they have (Virtual items)
The issue that I am having is that in the GUI it is displaying 'null' instead of how many they have... Could anyone help me please?
Item in the gui
Code for creating the player's instance in the config (Using a custom file class that was provided to me by a friend of mine.)
#EventHandler
public void playerJoin(PlayerJoinEvent event) {
Main main = Main.getPlugin(Main.class);
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
if (!main.getDataFolder().exists())
main.getDataFolder().mkdirs();
File file = new File(main.getDataFolder(), "players.yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
if (!config.contains("Users." + uuid + ".Username")) {
try {
System.out.println("Creating entry for " + player + " (" + uuid + ")");
config.set("Users." + uuid + ".Username", player);
config.set("Users." + uuid + ".Packages.Common", 0);
config.set("Users." + uuid + ".Packages.Rare", 0);
config.set("Users." + uuid + ".Packages.Epic", 0);
config.set("Users." + uuid + ".Packages.Legendary", 0);
config.set("Users." + uuid + ".Packages.Exotic", 0);
config.save(file);
System.out.println("Successfully created the entry for " + " (" + uuid + ")");
} catch (Exception e) {
}
}
}
Code for the creation of the item in the gui:
public static String inventoryname = Utils.chat("&fWhite Backpack");
public static Inventory WhiteBackpack(Player player) {
UUID uuid = player.getUniqueId();
Inventory inv = Bukkit.createInventory(null, 27, (inventoryname));
ItemStack common = new ItemStack(Material.INK_SACK);
common.setDurability((byte) 8);
ItemMeta commonMeta = common.getItemMeta();
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l" + Main.pl.getFileControl().getConfig().getString("Users." + uuid + ".Packages.Common")));
common.setItemMeta(commonMeta);
inv.setItem(10, common);
return inv;
}
There are a couple things wrong with your code.
First, you never account for what happens if the config you are loading does not exist. When you do main.getDataFolder().mkdirs(), you account for if the folder is missing, but not the file.
Second, you are doing the following operation:
config.set("Users." + uuid + ".Username", player);
This is incorrect because the player variable is of the type Player, not of the type String. To fix this, you need to instead do the following:
config.set("Users." + uuid + ".Username", player.getName());
Third, you are attempting to write to a file that might not exist. When you initialize you file, you need to also make sure it exists, and if it does not, you need to create it. Right now you have the following:
File file = new File(main.getDataFolder(), "players.yml");
It must be changed to this block of code:
File file = new File(main.getDataFolder(), "players.yml");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
}
You could just have it be created when you attempt to save the file later on, but that is not ideal since it's safer to let Bukkit write to a file that already exists.
Fourth, and I'm not necessarily sure that this is a problem per se, but you are trying to access an Integer value from the config file as if it were a String. Try to replace the following:
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l"
+ Main.pl.getFileControl().getConfig().getString("Users." + uuid + ".Packages.Common")));
with this instead:
commonMeta.setDisplayName(Utils.chat("&fCommon Packages &8» &f&l"
+ Main.pl.getFileControl().getConfig().getInt("Users." + uuid + ".Packages.Common")));
Hope this gets you moving in the right direction!

cursor count is 1 whereas the table has 3 rows

I m trying to populate sql table and then retrieve data from it. Following is my code.
public void addQuestion(Question quest)
{
int id = 1;
ContentValues values = new ContentValues();
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_QUEST1);
onCreate(db);
values.put(KEY_QUES, quest.getQuestion());
values.put(KEY_ANSWER, quest.getAnswer());
values.put(KEY_OPTA, quest.getOptA());
values.put(KEY_OPTB, quest.getOptB());
values.put(KEY_OPTC, quest.getOptC());
db.insert(TABLE_QUEST1, null, values);
System.out.println("Added in database: " + quest.getQuestion());
}
public ArrayList<Question> getAllQuestions() {
System.out.println("getting rows 1");
ArrayList<Question> quesList = new ArrayList<Question>();
System.out.println("getting rows 2");
Cursor cursor = null;
SQLiteDatabase db = getReadableDatabase();
System.out.println("getting rows ");
cursor = db.rawQuery("SELECT * FROM " + TABLE_QUEST1, null);
if (!cursor.moveToFirst()) {
System.out.println("No data in the database ");
} else {
System.out.println("theres data in the database ");
quesList = new ArrayList<Question>();
do {
System.out.print("total rows " + cursor.getCount());
Question quest = new Question();
quest.setID(cursor.getInt(0));
quest.setQuestion(cursor.getString(1));
quest.setAnswer(cursor.getString(2));
quest.setOptA(cursor.getString(3));
quest.setOptB(cursor.getString(4));
quest.setOptC(cursor.getString(5));
quesList.add(quest);
} while (cursor.moveToNext());
cursor.close();
}
}
I have 4 rows of data in my table and I can see that with the print statement "added in database"
but when i actually read it the cursor just reads row 1 and moves out of the while loop. what could potentially be wrong.
tia
Your code was absolutely fine except placing drop command in the loop. As mentioned in the earlier comments, please make sure to avoid calling drop query each time and you'll find the result.
As Santosh has pointed out DROPPING the table (as per db.execSQL("DROP TABLE IF EXISTS " + TABLE_QUEST1);) and then re-creating it (as per onCreate(db);) will delete the table and then re-create the table removing any rows/data that had previously been added to the table.
As such it's simply a matter of removing those two lines of code, Also there appears to be no need for the line int id = 1;, so perhaps remove this, as per :-
public void addQuestion(Question quest)
{
ContentValues values = new ContentValues();
SQLiteDatabase db = this.getWritableDatabase();
values.put(KEY_QUES, quest.getQuestion());
values.put(KEY_ANSWER, quest.getAnswer());
values.put(KEY_OPTA, quest.getOptA());
values.put(KEY_OPTB, quest.getOptB());
values.put(KEY_OPTC, quest.getOptC());
db.insert(TABLE_QUEST1, null, values);
System.out.println("Added in database: " + quest.getQuestion());
}
P.S. you may consider not using hard coded column offsets but instead obtain offsets according to column names by utilising the getColumnIndex(column_name) Cursor method. e.g. :-
Question quest = new Question();
quest.setID(cursor.getInt(cursor.getColumnIndex("name_of_your_id_columm")));
quest.setQuestion(cursor.getString(cursor.getColumnIndex(KEY_QUES)));
quest.setAnswer(cursor.getString(cursor.getColumnIndex(KEY_ANSWER)));
quest.setOptA(cursor.getString(cursor.getColumnIndex(KEY_OPTA)));
quest.setOptB(cursor.getString(cursor.getColumnIndex(KEY_OPTB)));
quest.setOptC(cursor.getString(cursor.getColumnIndex(KEY_OPTC)));
quesList.add(quest);
Noting that instead of "name_of_your_id_columm", you may have something like KEY_ID defined, if so use that, thus you have a single definition so it reduces the chance of inadvertently mispelling column names or miscalculating the offsets.

Select query on postgresql database result is empty. Am I using wrong logic?

I am using Npgsql for postgresql in C++/CLI. So, the problem is, I have a db on my computer, and I am trying to select some of data from it's "movies" table. I already entered some data inside it, so I know that it has some data. But when I try to select some of them, answer to my query is empty. My code is like below:
public: string* SelectData(string* torrent)
{
conn->Open();
String ^ query = "SELECT title, director, actors, genre FROM movies";
Npgsql::NpgsqlCommand ^ command = gcnew NpgsqlCommand(query, conn);
try{
Npgsql::NpgsqlDataReader ^ dr = command->ExecuteReader();
for (int i = 0; i < N_TORRENT; i++)
{
if(dr->Read())
{
string std1 = toStandardString((String^)dr[0]);
string std2 = toStandardString((String^)dr[1]);
string std3 = toStandardString((String^)dr[2]);
string std4 = toStandardString((String^)dr[3]);
torrent[i] = std1 + " " + std2 + " " + std3 + " " + std4;
}
}
return torrent;
}
finally{
conn->Close();
}
}
(For the ones who will look for this question's answer)
Problem solved when I changed my query and look for the "title" column that are not empty. But this is ridiculus, so I beleive the problem was about pgAdmin. Because my insert query was not working either, but I added "rowseffected" variable and it shows the effected row's number and looks like it is working. So the problem is probably about the pgAdmin.

How to enable Seperate Audits Table in Entity Framework

I have a Entity Framework based database with a few entities/models/table. For e.g. Documents Model, I am want to track all changes to each record in that table, in a seperate table called DocumentChanges Model/Table.
Could you please guide me on how to enable/tell EF to track/audit all changes to the table in a separate table?, not just a date time stamp, but save the full record for every change in a separate table.
The library Audit.EntityFramework can help you to do what you want.
You'll need to implement your own DataProvider to store the data formatted as you wish.
For example:
void StartUp()
{
//Setup to use your own provider to store the data
Audit.Core.Configuration.Setup()
.UseCustomProvider(new YourDataProvider());
//Setup to audit EF operations only for the table Documents
//(Your DbContext must inherit from AuditDbContext)
Audit.EntityFramework.Configuration.Setup()
.ForAnyContext(x => x.IncludeEntityObjects())
.UseOptIn()
.Include<Documents>();
}
class YourDataProvider : AuditDataProvider
{
public override object InsertEvent(AuditEvent auditEvent)
{
//Get some enviroment info:
var userName = auditEvent.Environment.UserName
//Get the complete log for the EF operation:
var efEvent = auditEvent.GetEntityFrameworkEvent();
foreach(var entry in efEvent.Entries)
{
// each entry is a modified entity (updated, deleted or inserted)
if (entry.Action == "Update")
{
//You can access the column values
var value = entry.ColumnValues["ID"];
//...or the columns changes
var changes = entry.Changes.Select(ch => ch.ColumnName + ": " +
ch.OriginalValue + " -> " + ch.NewValue);
}
//... insert into DocumentChanges table
}
return id;
}
}

Parse query to print all results in a given time frame

I would like to create a query that will allow a user to type in a starting date, and print out all records of a table from that date until the current time. I keep getting "Error 102: invalid field type for find". Any suggestions?
function billingReport(){
startDate = new Date(document.getElementById("startDate").value);
var caseList = Parse.Object.extend("Cases");
var query = new Parse.Query(caseList);
query.greaterThanOrEqualTo("createdAt", "startDate");
query.find({
success: function(results) {
alert("Successfully retrieved " + results.length + " scores.");
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
alert(object.id + ' - ' + object.get('playerName'));
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
mentioned in a comment above, but I just wanted to end this topic correctly. The two date objects were of different types, so i added .toISOString to the startDate object and it worked like a charm