I have an initial selection which I place into list. I use the list to loop through each record and where it meets certain criteria I run trough a series of inserts, deletes and updates. Finally call the SaveChanges() method to commit changes.
The code runs through without raising an exception but no changes reflect in the database. I have been searching the web with no luck.
I'm using VS2008 with SQL2008 backend.
Please help?
using (SMSEntities db = new SMSEntities())
{
try
{
//Get SMS's to send from Inbox
List<Inbox> tmpInbox = (from c in db.Inboxes where c.Status != "NEW" && c.Status != "SUCCESS" select c).ToList();// new { Inbox.InboxID, Inbox.StatusTrackingID, Inbox.Status, Inbox.NoOfAttempts, Inbox.CellNo, Inbox.SourceCellNo, Inbox.Header, Inbox.Message, Inbox.MessageDate, Inbox.AccountID, Inbox.LastAttemptDate }).ToList();
foreach (Inbox tmpInboxIndex in tmpInbox)
{
bool success = false;
//Check status here
string SentStatus = CheckSMSSentToProvider(tmpInboxIndex.StatusTrackingID);
// Define a transaction scope for the operations.
using (TransactionScope transaction = new TransactionScope())
{
try
{
if ((SentStatus == "DELIVERED") || (SentStatus == "NOTFOUND") || (SentStatus == "DELETED") || (SentStatus == "REJECTED") || (SentStatus == "UNDELIVERED"))
{
//Insert the Log row
Log newLog = new Log();
newLog.InboxID = tmpInboxIndex.InboxID;
newLog.CellNo = tmpInboxIndex.CellNo;
newLog.SourceCellNo = tmpInboxIndex.SourceCellNo;
newLog.Message = tmpInboxIndex.Message;
newLog.Header = tmpInboxIndex.Header;
newLog.MessageDate = tmpInboxIndex.MessageDate;
newLog.AccountID = tmpInboxIndex.AccountID;
newLog.ProcessedDate = DateTime.Now;
newLog.Status = tmpInboxIndex.Status;
newLog.StatusTrackingID = tmpInboxIndex.StatusTrackingID;
newLog.NoOfAttempts = tmpInboxIndex.NoOfAttempts;
newLog.LastAttemptDate = tmpInboxIndex.LastAttemptDate;
db.Logs.AddObject(newLog);
//Delete the Inbox row
if (tmpInbox != null)
{
var deleteInbox = (from c in db.Inboxes where c.InboxID == tmpInboxIndex.InboxID select c).FirstOrDefault();
if (deleteInbox != null)
{
db.DeleteObject(deleteInbox);
//db.SaveChanges(SaveOptions.DetectChangesBeforeSave);
}
}
}
else
{
//Update inbox status
var tmpUpdateInbox = (from c in db.Inboxes where c.InboxID == tmpInboxIndex.InboxID select c).FirstOrDefault();
tmpUpdateInbox.Status = SentStatus;
tmpUpdateInbox.NoOfAttempts = tmpInboxIndex.NoOfAttempts + 1;
tmpUpdateInbox.LastAttemptDate = DateTime.Now;
//db.SaveChanges(SaveOptions.DetectChangesBeforeSave);
}
// Mark the transaction as complete.
transaction.Complete();
success = true;
//break;
}
catch (Exception ex)
{
// Handle errors and deadlocks here and retry if needed.
// Allow an UpdateException to pass through and
// retry, otherwise stop the execution.
if (ex.GetType() != typeof(UpdateException))
{
Console.WriteLine("An error occured. "
+ "The operation cannot be retried."
+ ex.Message);
break;
}
// If we get to this point, the operation will be retried.
}
}
if (success)
{
// Reset the context since the operation succeeded.
//db.AcceptAllChanges();
db.SaveChanges();
}
}
// Dispose the object context.
db.Dispose();
}
catch (Exception exp)
{
throw new Exception("ERROR - " + exp.Message.ToString(), exp);
}
}
return true;
Regards,
GPR.
Are you using a local database file? You may be looking for changes in the wrong place. By default, when the program starts, VS copies the database file into the debug or release folder. Then the program runs and changes are made, and saved, to the file in the debug or release folder. The program ends, and when you look at the database in your source folder it looks the same. You can change the connection string in the app.config to use an absolute path to avoid this.
See http://blogs.msdn.com/b/smartclientdata/archive/2005/08/26/456886.aspx for more info
The TransactionScope is useless if you do not put the call to SaveChanges into it.
Either move the call to SaveChanges into it or remove the TransactionScope completely.
Related
Please see the code herein under:
function binanceOrderBook() {
try {
muteHttpExceptions = true;
var workSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var mySheet = workSpreadsheet.getSheetByName('Order Books');
if(mySheet == 'Sheet'){
mySheet.activate();
} else {
mySheet = workSpreadsheet.insertSheet('Order Books', 1).activate();
}
var ui = SpreadsheetApp.getUi();
var string = 'https://api.binance.com/api/v3/depth?';
var symbolResponse = ui.prompt('Pair Name', 'Please enter the pair symbol.\n\nExamples: BTCUSDT or ETHBTC:', ui.ButtonSet.OK_CANCEL);
var symbolButton = symbolResponse.getSelectedButton();
if(symbolButton == ui.Button.CANCEL){return}
var mySymbol = symbolResponse.getResponseText();
mySymbol = mySymbol.toUpperCase();
string = string + "symbol=" + mySymbol;
var limitResponse = ui.prompt('Limit:', 'Please enter Limit (Period Quantity).\nValid limits are:5, 10, 20, 50, 100, 500, 1000. \n Default limit is 100.\n You can leave it blank and simply click OK.', ui.ButtonSet.OK_CANCEL);
if(limitResponse.getSelectedButton() == ui.Button.CANCEL){return}
var myLimit = Number(limitResponse.getResponseText());
if(myLimit != 5 && myLimit != 10 && myLimit != 20 && myLimit != 50 && myLimit != 100 && myLimit != 500 && myLimit != 1000){myLimit = 100;}
string = string + "&limit=" + myLimit;
var myDate = new Date().toUTCString();
var jsonOrderBookData = JSON.parse(UrlFetchApp.fetch('https://api.binance.com/api/v3/depth?symbol=' + mySymbol + '&limit=' + myLimit));
reporter(jsonOrderBookData);
} catch (e){
exceptionHandler(e)
}
}
The problem I have is to run UrlFetchApp.fetch again when it encounters an error. I need to run it several times to get the result. So, I need to prevent the script from stopping when an error (code -1003) occurs, but how can I do that?
EDIT: There is a function windows.onerror in javascript which can be set to prevent the program from stopping. Is it useable in GAS? if yes, how? if No, is there a similar solution for GAS?
You could call binanceOrderBook() from within your catch statement. E.g.
...
} catch (e){
binanceOrderBook()
exceptionHandler(e)
}
Of course you probably should have some condition that exits the function if a certain error occurs, or if you know that the function needs to run no more than x number of times you could check that it has run less than x times before executing. For example,
const maxValue = 10 // whatever the max number of executions should be
function binanceOrderBook(executions) {
if (executions >= maxValue) return;
try {
...
} catch(e) {
binanceOrderBook((executions || 0) + 1));
exceptionHandler(e); // note that I am including this here because it's in your original example, but as it is written now, exception handler won't be called until binanceOrderBook executes without an error.
}
}
[Edit] To answer your second question, there is no equivalent to window.onerror that I know of in GAS. However, window.onerror is a global event handler and so would affect errors thrown by any functions defined in your project. To address a concern with a single function call like this, you are better off using a try catch statement as you have.
It errors out when the record couldn't be found Cannot read property 'id' of undefined
How can I keep it from crashing out and handle "undefined"?
let blacklisted = false;
let conStr = "SELECT * FROM `blacklist` WHERE `id` = '"+message.author.id+"'";
con.query(conStr, function(error, result, field) {
console.log(result[0].id);
if(result[0].id){
console.log("Van")
blacklisted = false;
}
});
if (message.author.id !== "397487086522990602" && blacklisted){/*Actual Code*/}
I believe you should add proper checks. Try catch is basically for connection/ query execution related failure not for if data not returned.
So just add check if result[0] exists.
Hence folowing code should serve your purpose:
let blacklisted = false;
let conStr = "SELECT * FROM `blacklist` WHERE `id` = '"+message.author.id+"'";
con.query(conStr, function(error, result, field) {
if(result[0] && result[0].id){ // add check for result[0]
console.log("Van")
blacklisted = false;
}
});
if (message.author.id !== "397487086522990602" && blacklisted){/*Actual Code*/}
I want so every added\changed record will have a time stamp of creation\change.
But - so it will be easy to embed and easy to manage - automatically.
Overwrite the 'DbContext' class or embed this in the '.tt' file (Codefirst \ DBFirst)
The code assume so you have the fields 'CreatedOn'\'ModifiedOn' inside the POCO.
If you don't have them, or you have only one - the code will work fine.
Be aware! If you use a extension (as this one) so allow you to do batch updates or changes from a stored procedure - this will not work
EDIT:
I found the source of my inspiration - thanks 'Nick' here
public override int SaveChanges()
{
var context = ((IObjectContextAdapter)this).ObjectContext;
var currentTime = DateTime.Now;
var objectStateEntries = from v in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
where v.IsRelationship == false && v.Entity != null
select v;
foreach (var entry in objectStateEntries)
{
var createdOnProp = entry.Entity.GetType().GetProperty("CreatedOn");
if (createdOnProp != null)
{
if (entry.State == EntityState.Added)
{
if (createdOnProp != null)
{
createdOnProp.SetValue(entry.Entity, currentTime);
}
}
else
{
Entry(entry.Entity).Property("CreatedOn").IsModified = false;
}
}
var modifiedOnProp = entry.Entity.GetType().GetProperty("ModifiedOn");
if (modifiedOnProp != null)
{
modifiedOnProp.SetValue(entry.Entity, currentTime);
}
}
return base.SaveChanges();
}
I'm getting this error in my handler function but I've no clue what's causing it. I've copied the code and debugged it in a non-handler function and there was no error.
function _responseToNext(e) {
var app = UiApp.getActiveApplication();
app.getElementById('btnPrev').setEnabled(true);
var current = parseInt(CacheService.getPublicCache().get('currentItem'));
var agendaItems = Utilities.jsonParse(CacheService.getPublicCache().get('agenda'));
agendaItems[current]['notes'] = e.parameter.tAreaNotes;
agendaItems[current]['status'] = e.parameter.lboxStatus;
CacheService.getPublicCache().put('agenda', Utilities.jsonStringify(agendaItems));
current = current + 1;
CacheService.getPublicCache().put('currentItem', current);
fillAgendaDetail(app);
// only enabled 'Next' if there are more items in the agenda
if (current < agendaItems.length-1) {
app.getElementById('btnNext').setEnabled(true);
}
return app;
}
I suppose, the error cause is that the Cache get method returns null during the 1st execution when the cache is empty. The Utilities.jsonParse throws an exception and the cache becomes in any case empty. Try to use the following modified code.
function _responseToNext(e) {
var app = UiApp.getActiveApplication();
app.getElementById('btnPrev').setEnabled(true);
var cachedCurrent = CacheService.getPublicCache().get('currentItem');
var current;
if (cachedCurrent == null) {
current = 0;
}
else {
current = parseInt(cachedCurrent);
}
var cachedAgendaItems = CacheService.getPublicCache().get('agenda');
var agendaItems;
if (cachedAgendaItems == null) {
agendaItems = [][];
}
else {
agendaItems = Utilities.jsonParse();
}
agendaItems[current]['notes'] = e.parameter.tAreaNotes;
agendaItems[current]['status'] = e.parameter.lboxStatus;
CacheService.getPublicCache().put('agenda', Utilities.jsonStringify(agendaItems));
current = current + 1;
CacheService.getPublicCache().put('currentItem', current);
fillAgendaDetail(app);
// only enabled 'Next' if there are more items in the agenda
if (current < agendaItems.length-1) {
app.getElementById('btnNext').setEnabled(true);
}
return app;
}
Also please mention that the Public Cache (CacheService.getPublicCache()) is the same for all users of your script. In your case, this means, if two users user1#example.com and user2#example.com use the script they will have the same current and agendaItems variables values, i.e. it can be a situation when the _responseToNext handler is already executed under the user1 authority - the current variable is equal to 1, after the user2 executes the _responseToNext handler - the current variable is equal to 2 and so on. If you do not need such behaviour, use the CacheService.getPrivateCache().
I'm writing a sort of interface between a TCP Chat server and an SQL Server, and while working on a part where a user submits a value and is assigned a named pulled from a row in this DB with this value. When querying this DB with a value from a telnet shell, I can't get any results from the DB. But I can when I perform the same query in adminer/MySQL # BASH etc...
My thoughts are that it has come down to an encoding issue. Being rather noobish to node, I don't really know what to do. I do have a pretty good experience with JavaScript, just not node.
Code
function setCliNameOrKick(client, key){
key = String(key).replace(/\n\r\b\\\s/gi, "");
var q = "SELECT username FROM webusers WHERE lic = \'"+String(key).toString()+"\'; --";
console.log(key);
query(q);
cli.query(q, function cb(e, r, f){
if(client != null){
console.log(r);
if(r.length >= 1){
client.name = r['username'];
}else{
client.stream.end();
}
}else{
console.log("Was Passed A Null Client!");
}
});
}
That comes from the DB query tool
It takes input from a string sent by the client on connect, alongside an object representing the client
stream.addListener("data", function(data){
if(client.name == null){
data = String(data).replace(new RegExp("[\n]+", "g"), "");
cNameBuff = cNameBuff + data;
if(cNameBuff.length > 1){ //Min Length
//client.name = cNameB;
db.set(client, cNameBuff);
onAuth(client);
}
return;
}
data = String(data);
if(data.length >= 2){
srv.procChat(client, data);
}
});