When I try to call Dexie on a database on which another call has been done by IndexedDB, there rises an error that the connection is already made to the database.
Can we pass an existing connection to Indexedb to Dexie?
This can be helpful when we want to use same connection in a Dexie object and another object and this happens to me when I try to add Dexie to my project. I don't want to rewrite the existing function.
Example:
function initDataBase(callback){
if(window.indexedDB){
var requeteBDD = window.indexedDB.open("databasename",1);
requeteBDD.onsuccess = function(){
if(typeof callback == "function")
callback(requeteBDD.result);
};
}
}
So can we do,for instance
initDataBase(function(db){
var dex = new Dexie(db);
});
I would like to use same connection as the first one.
Is it possible?
It's not possible as of current version to pass an instance of IDBDatabase into Dexie constructor. However, this would definitely be an easy pull request to do in the source, as Dexie already has the ability to open existing database by name and adapt to it's existing schema.
However, you should not get an error if you instanciate multiple IDBDatabases to same database name unless one of them tries to upgrade it using another version.
Dexie can open an existing database without creating the schema (even though you can only pass a name and not the db instance), as shown in the following fiddle: https://jsfiddle.net/dfahlander/b8Levamm/
new Dexie('MyDatabase').open().then(function (db) {
log ("Found database: " + db.name);
log ("Database version: " + db.verno);
db.tables.forEach(function (table) {
log ("Found table: " + table.name);
log ("Table Schema: " +
JSON.stringify(table.schema, null, 4));
});
}).catch('NoSuchDatabaseError', function(e) {
// Database with that name did not exist
log ("Database not found");
}).catch(function (e) {
log ("Oh uh: " + e);
});
(which fails because the given DB is not there. But if you create it on jsfiddle and run it again, you'll see it open).
Related
I tried to create a stored procedure using the sample sp creation code from Azure docs, but i couldn't fetch the collection details. It always returns null.
Stored Procedure
// SAMPLE STORED PROCEDURE
function sample(prefix) {
var collection = getContext().getCollection();
console.log(JSON.stringify(collection));
// Query documents and take 1st item.
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM root r',
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no docs found');
}
else {
var response = getContext().getResponse();
var body = { prefix: prefix, feed: feed[0] };
response.setBody(JSON.stringify(body));
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
The console shows only this.
the results shows no doc found because of not getting collection.I have passed the partition key at time of execution via explorer.
I had a similar issue. I think the Azure portal doesn't execute stored procedures properly when the partition key is not a string.
In my case I had a partitionKey that is a number. When I executed the stored procedure via the portal I always got an empty resultSet, even though I had documents in my database. When I changed the structure a little, and made my partitionKey a string, the stored procedure worked fine.
Did you create the ToDoList Database with the Items Collection? Yo can do this from the Quick start blade in the Azure portal.
And then create an SP to run against that collection. There is no partition key required, so no additional params are required (leave blank).
The Collection is created without any documents. You may choose to add documents via the Query Explorer blade or via the sample ToDoList App that is available via the Quick start blade.
You are debugging in a wrong way.
It is perfectly fine to see "{\"spatial\":{}}" in your console log, even if the collection has items. Why? well because that is a property of that object.
So regarding what you said:
the results shows no doc found because of not getting collection
is false. I have the same console log text, but I have items in my collection.
I have 2 scenarios for why your stored procedure return no items:
I had the same issue trying on azure portal UI(in browser) and for my surprise I had to insert an item without the KEY in order that my stored procedure to see it.
On code you specify the partition as a string ie. new PartitionKey("/UserId") instead of your object ie. new PartitionKey(stock.UserId)
We need to update the all the documents in a collection to change their shape. We'd like to record an audit of the change in a different collection where we will store a document which contains the old and new version. In order to make this change atomic, we are using a stored proc.
The issue we are facing is updating another collection from a stored proc. It seems the audit document is always written into the collection the stored proc belongs to.
I have written up a sample stored proc:
function sample(prefix) {
var context = getContext();
var fooCollection = context.getCollection();
var barCollection = context.getCollection("BarCollection");
// Query documents and take 1st item.
var isAccepted = fooCollection.queryDocuments(
fooCollection.getSelfLink(),
'SELECT * FROM root r',
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
if (!feed || !feed.length) context.getResponse().setBody('no docs found');
else {
var fooDoc = feed[0];
var barDoc = {
"foo" : fooDoc,
"bar" : "bar"
}
var isAccepted2 = barCollection.createDocument(barCollection.getSelfLink(), barDoc);
if (!isAccepted2) throw new Error('The query was not accepted by the server.');
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
In this sample, my stored proc is saved in the FooCollection. I get a document and try to save a copy into the BarCollection. The new document is always saved into the FooCollection.
Is this scenario supported in Document DB? If so, what changes do I need to make the stored proc to make it work?
DocumentDB stored procedures are collection-scoped. You will not be able to write audit info to a separate collection; you'd need to write to the same collection.
I have a web app, that manages a budget for a user.
In the settings page, I can edit the budget, after clicking "save" I return to the main page, and there I have line that states the budget amount.
The problem is, that when I log in, I see the correct budget, after editing the budget and returning to the main page, I still see the old amount. Only after logging out and re-login again, that line in the main page updates to new amount.
Any solutions?
The code that saves the new budget:
$("#saveNewBudgetAmount").click(function(){
var User = Parse.User.extend("User");
var query = new Parse.Query(User);
var newBudget = $("#newBudgetSum").val();
query.equalTo("objectId", Parse.User.current().id);
query.first({
success: function (User) {
User.save(null, {
success: function (user) {
User.set("budget", newBudget);
User.save();
location ="Mainpage.html";
}
});
}
});
});
and the code that displays it on the main page:
var MBudget = (function () {
if (Parse.User.current()) {
return("Your monthly budget is:" +" "+Parse.User.current().get("budget")+" "+"<a href=Settings.html>(Edit)</a>");
}
A few things are happening.
First you should simplify your code, and use both alerts AND error handling so that you know if your code works, and when callbacks are made. You are also calling .save() once before any new values are set, so you have a useless save.
You also need to have a success and error callback for EVERY save function you use - .save() by itself is an asynchronous method, and since you are not calling a success function within your save method, so your app will navigate back to "Mainpage.html" before it is known whether or not the save function worked. Here is a much better implementation:
var newBudget = $("#newBudgetSum").val();
var currentUser = Parse.User.current();
currentUser.save(
{
// Set as many properties as you like in this field,
// think of it as a JSON object except you don't
// have to enclose the values in strings.
budget : newBudget,
}, {
success: function(user) {
alert("Budget successfully saved, new budget is: " + user.get("budget"));
},
error: function(error) {
// error functions will always have an error argument handed back to the client,
// with properties error.code and error.message. Error messages are incredibly useful.
alert("Budget save failed, error: " + error.code + " " + error.message);
}
});
Another tip is that I recommend all users of Parse.com to use alert() messages for their success and error callbacks while in development, for many reasons - but the key reasons are 1) it will alert you to whether or not the code worked, and 2) it will prevent accidental bugs from causing infinite requests to the Parse.com server, which does happen sometimes, and will cause them to charge your account.
The problem is this api : Parse.User.current() never sync data in the cloud. The data of Parse.User.current() is derived from localstorage. You have to refresh it manually by calling save or fetch method on it.
Parse.User.Current() return normal Parse.User object. You can use it directly without querying in advance. So you can just rewrite your first codes as following :
$("#saveNewBudgetAmount").click(function() {
var user = Parse.User.current() ;
var newBudget = $("#newBudgetSum").val();
user.set("budget", newBudget);
user.save(null,{
success: function(user) {
// feedback user and redirect page.
},
error: function(user, error) {
//You should always handle error.
console.error(error.message) ;
}
}) ;
});
With this code, the local data would refresh when ths save() call done successfully. On your main page the budget value of Parse.User.current() object would be correct.
I have a PFObject that has an array key. I can successfully call addObject: on this PFObject, and can confirm that the object has been added to the array key properly using an NSLog. However, when I try to save the PFObject to Parse, even though it says everything went successful, the changes are not shown in the Data Browser.
I have tried everything, and can even get this to work in an older version of my app, but for some reason it will not work anymore.
I posted another StackOverflow question about this here
The only response I got were some comments saying that I should trigger a "before save" function and log everything via Cloud Code. The problem is I don't know javascript, and I've been messing around with Cloud Code and nothing's happening.
Here is the code I am executing in my app:
[self.message addObject:currentUsersObjectId forKey:#"myArrayKey"];
And then I am using saveInBackgroundWithBlock:
I need to alter Cloud Code so that it will check the self.message object's "myArrayKey" before saving and log the results.
Edit 2:
Here is how I create currentUsersObjectId:
NSString *currentUsersObjectId = [[NSString alloc]init];
PFUser *user = [PFUser currentUser];
currentUsersObjectId = user.objectId;
Edit 3:
Here is the save block
[self.message saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"An error has occurred.");
}
}];
Edit 4:
After adding Timothy's cloud code, the saveInBackgroundWithBlock: now does not successfully complete. Instead an error occurs, and the error object NSLogs as `"Error: Uncaught Tried to save an object with a pointer to a new, unsaved object. (Code: 141, Version: 1.2.17)" and also as:
Error Domain=Parse Code=141 "The operation couldn’t be completed. (Parse error 141.)" UserInfo=0x15dc4550 {code=141, error=Uncaught Tried to save an object with a pointer to a new, unsaved object.} {
code = 141;
error = "Uncaught Tried to save an object with a pointer to a new, unsaved object.";
}
Here is my complete Cloud Code file after adding Timothy's code:
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId;
//newColText = request.params.newColText;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
var currentUser = request.user;
var relation = user.relation("friendsRelation");
relation.add(currentUser);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
Parse.Cloud.beforeSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saving message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
// log the after-save too, to confirm it was saved
Parse.Cloud.afterSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saved message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
After much back and forth, I'm stumped as to why this isn't working for you. As for logging in Cloud Code, if you follow the guide on adding code you can add the following to your main.js and deploy it:
Parse.Cloud.beforeSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saving message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
// log the after-save too, to confirm it was saved
Parse.Cloud.afterSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saved message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
With those in place you have plenty of server-side logging that you can check.
I am adding my own answer in addition to Timothy's in case anyone else is having a problem similar to this. My app uses the following library to allow parse objects to be stored using NSUserDefaults: https://github.com/eladb/Parse-NSCoding
For whatever reason, after unarchiving the parse objects, they are not able to be saved properly to the Parse database. I had to query the database using the unarchived one's objectId and retrieve a fresh version of the object, and then I was able to successfully make changes to and save the retrieved object.
I have no idea why this is happening now. I have never had any problems until about two weeks ago when I tried to deploy a new version of my cloud code, and if I remember correctly, Parse wanted me to update the Parse SDK or the Cloud Code version before I could deploy it.
These changes must not be compatible with these categories.
I have the following code. The idea is that I update a database row in an interval, however if I remove the row manually from the database while this script runs, the save() still goes into success(), but the row is not actually put back into the database. (Because sequelize does an update query with a where clause and no rows match.) I expected a new row to be created or error() to be called. Any ideas to what I can do to make this behave like I want to?
var Sequelize = require("sequelize")
, sequelize = new Sequelize('test', 'test', 'test', {logging: false, host: 'localhost'})
, Server = sequelize.import(__dirname + "/models/Servers")
sequelize.sync({force: true}).on('success', function() {
Server
.create({ hostname: 'Sequelize Server 1', ip: '127.0.0.1', port: 0})
.on('success', function(server) {
console.log('Server added to db, going to interval');
setInterval(function() { console.log('timeout reached'); server.port = server.port + 1; server.save().success(function() { console.log('saved ' + server.port) }).error(function(error) { console.log(error); }); }, 1000);
})
})
I'm afraid what you are trying to do is not currently supported by sequelize.
Error callbacks are only ment for actual error situations, i.e. SQL syntax errors, stuff like that. Trying to update a non-existing row is not an error in SQL.
The import distinction here is, that you are modifying your database outside of your program. Sequelize has no way of knowing that! I have two possible solutions, only one of which is viable right now:
1 (works right now)
Use sequelize.query to include error handling in your query
IF EXISTS (SELELCT * FROM table WHERE id = 42)
UPDATE table SET port = newport WHERE id = 42
ELSE
INSERT INTO table ... port = newport
Alternatively you could create a feature request on the sequelize github for INSERT ... ON DUPLICATE KEY UPDATE syntax to be implemented see and here
2 (will work when transactions are implemented
Use transactions to first check if the row exists, and insert it if it does not. Transactions are on the roadmap for sequelize, but not currently supported. If you are NOT using connection pooling, you might be able to acomplish transactions manually by calling sequelize.query('BEGIN / COMMIT TRANSACTION').