How does mongodb create database/collection on the fly - javascript

Mongodb is cool enough to create the database/collection on the fly, if we run a code similar to
db.store.save({a: 789});
It automatically creates store collection and add a document to it.
My javascript understanding says it is not possible to call a method on an undefined property of db object. It should have resulted in some kind of error/exception.
I am curious to understand the happenings behind the scene and if there is any helpful link please point me to those. Googling did not help me much.

In JavaScript there is a way to define a function that will be executed when an undefined method is called.
Example:
var o = {
__noSuchMethod__: function(id, args) { console.log(id, '(' + args.join(', ') + ')'); }
};
o.foo(1, 2, 3);
o.bar(4, 5);
o.baz();
// Output
// foo (1, 2, 3)
// bar (4, 5)
// baz ()
Note this is a non-standard feature and today only works in Firefox.
I do not know how MongoDB implemented this feature, but I'm just responding in order to report that can be done this way.
Fot more details see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod

As I recall in a NodeJS environment you must do something like this to actually create a record: db.get('collectionName').insert({..something...}); or db.get('collectionName').save({...something...}); but you don't get to use the collection name as a property of db.
The line you're mentioning is only used in MongoDB shell, which is not Javascript.
I guess you're misunderstanding what's MongoDB shell and what's a MongoDB driver.
So long story short MongoDB (driver) is not able to access an undefined property.
EDIT
In response to your comment..
MongoDB JS driver's GitHub page pretty much points out how to insert a field and always uses the syntax I mentioned: https://github.com/mongodb/node-mongodb-native
As for what you're using in the shell it's pretty clear that you can't just use Javascript in a command shell. So I guess I'll point you to a place in which you can see in what language was MongoDB developed: http://www.mongodb.org/ pretty much the first line says it's written in C++.
Hope this helps clarify your question

Related

Collision detection, new Function

I use the library "Sinova / Collisions" on GitHub, with Node.js.
https://github.com/Sinova/Collisions
I need a function, to delete all data at once. There is a function to delete Objects one by one. But, that doesn't always work correctly.
All Collision saved in colArr "Array"
for(let i = 0; i < colArr.length; i++){
system.remove(colArr[i]);
}
Is there a Way to delete everything in the Library, directly? A new Function?
system.removeAll(); //???
I wrote to the Github-Issues a few days ago. But without Success
From reading the code, no such function exists, no.
If you want to start from scratch just create a new Collisions object and work with that.
Of course, unless you scope it carefully, or replace it, the old one will still exist and take up memory.
Making a feature request to the library author is a good idea, but we can't really help you to get any traction on that. You have to be patient and wait for a response from them.
var system = new Collisions();
Should fix the Problem

Javascript date test harness

I have written my own implementation of Date() in Javascript, BardyDate, which in addition to all the properties/methods of Date, does a bunch of other stuff. Why I have done this is a very good question indeed but it is such a long story I will save it for a rainy day.
But what I was thinking would be lovely would be to be able to verify that it still behaves correctly as a Date. I know nothing about test suites etc but wondered how I might apply any existing tests for the Javascript Date object to my BardyDate to show correctness?
Any advice very welcome.
I waited to respond because I am not certain that there are no Date test suites already out there for javascript. I wanted to give the benefit of the doubt to anyone who might know more.
However, as far as I know this sort of testing would all be done in browser building/validation. It certainly is possible to use some of the existing test suites from that realm of development, but I don't think it would be an easy task to set-up. Many of the browser's have a build process that you could fork (specifically you could isolate their date test cases). Within their test process you would have to find the given segment for Javascript Date objects, that would test to ensure w3 spec compatibility.
At that, Selenium is a very common and practical means of creating unit tests and if designed well integration tests for web-apps (hooking into the javascript as well), and is capable of producing nice reports on test results.
Lastly, a cummulative post on Javascript Testing libraries can be found on this post about Javascript TDD (Test Driven Design)
Or you could do something like the following (meant to be a guideline not a complete solution -- inspired by the comment from dandavis):
var epochTS = 0;
var bd = new BardyDate(epochTS);
var d = new Date(epochTS);
Object.getOwnPropertyNames(Date.prototype).forEach(function(dateFunction){
//in this if statement you are testing the functions like getTime() and getYear()
if(dateFunction.indexOf("get") == 0){
console.log("dateFunction " + dateFunction +
"() pass: " + (bd[dateFunction]() === d[dateFunction]()))
}
//in this if statement you are testing the functions like toString() and toJSON()
if(dateFunction.indexOf("to") == 0){
console.log("dateFunction " + dateFunction +
"() pass: " + (bd[dateFunction]() === d[dateFunction]()))
}
//then there are the 16 set methods, those you probably would want to hardcode.
//unless you are content with passing a hard coded value in like "10" -- the
//issue would be bounds testing, which you would likely want to hardcode.
//beyond the scope of this for-each loop.
})
A little explanation on the above snippet
With Object.getOwnPropertNames(Date.prototype) you can obtain all the methods of Date despite the fact that Date has the property DontEnum (see this post for more info).
Also you are able to treat each function string as a key within the javascript object hence the d[dateFunction]() which if dateFunction === "toString" would be interpreted/compiled down to d[toString]() which is equivalent to d.toString()

methods of Underscore.js in parse cloud code

I am trying to retrieve random 200 objects from the array returned to me by query.find() method. First i tried to implement all random number generation and all . And just now i got introduced to underscore.js method "_.sample" .
But something is going wrong. I dont have much knowledge of underscore.js. So if someone could help that will be great.
When i try to sun _.sample method it give me the error :
TypeError: Object function (e){if(e instanceof T)return e;if(!(this instanceof T))return new T(e);this._wrapped=e} has no method 'sample'
Someone please explain what exactly this error is. I tried searching but didn't get explanatory content. Thank you in advance.
Here's the code :
var queryPhrases = new Parse.Query("Phrases");
queryPhrases.select("phraseId");
queryPhrases.find().then(function(phrases){
var arrayOfUnused = _.sample(phrases,request.params.count);
user.add("usedPhrases",arrayOfUnused);
user.save();
response.success(arrayOfUnused) ;
});
Parse Cloud Code includes an outdated version of Underscore, but frustratingly, I can't find anything stating which version. While Underscore no longer ships with the Parse Javascript SDK as of v1.6.0 (late 2015), previously it had only used UnderscoreJS v1.4.4 (early 2013), so I'd expect Cloud Code to be using something from around then.
Adding the latest Underscore source to your Cloud Code is always an option, and then require it like any other of your own files.
Alternatively, I used the following to show a list of functions available in the included Underscore Cloud Code module.
var _ = require('underscore');
var availableFunctions = _.functions(_);
console.log('Available Underscore Functions: ' + JSON.stringify(availableFunctions));
Thanks a lot guys for your responses. I couldn't find the reason or the solution to run _.sample in my code. So i implemented it the other way. Here's what i did.
var arrayOfUnused = _.first(_.shuffle(phrases),request.params.count);
This works. :-)

Need help converting vbs code to jscript. Im getting a Runtime Error Type Mismatch

Ive got this labratory equipment that is connected to my PC. It uses special OCX file to communicate with the device (reading, setting parameters and such). I got this code from manual that seems to be working. I get a message box saying "Magnification =1272.814 Last error=API not initialized".
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>
So because I have 0% knowledge in vbs and about 10% in jscript I`m trying to rewrite the same thing in Javascript. And I also have some necessary code already written in js.
<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"\n Last error="+er);
Api1.ClosingControl();
</script>
Unfortunately I get a type mismatch error in either .Get or .GetLastError methods either with var value; var er; or var value=""; var er="";
Here is what API manual has to say
long GetLastError(VARIANT* Error)
[out] Error is the error string
associated with the error code for the last error
Remarks: This call will return a VT_BSTR VARIANT associated with the last error. Return
Value: If the call succeeds, it returns 0. If the call fails, an error
code is returned from the function.
long Get(LPCTSTR lpszParam, VARIANT* vValue)
[in] lpszParam is the name of the parameter e.g. “AP_MAG”
[in][out] vValue is the value of the parameter Remarks: This call will get the
value of the parameter specified and return it in vValue. In C++,
before calling this functions you have to specify the variant type
(vValue.vt) to either VT_R4 or VT_BSTR. If no variant type is defined
for vValue, it defaults to VT_R4 for analogue parameters (AP_XXXX) and
VT_BSTR for digital parameters (DP_XXXX). If the variant type is VT_R4
for an analogue parameter, then the floating point representation is
returned in the variant. If a VT_BSTR variant is passed, analogue
values are returned as scaled strings with the units appended (e.g.
AP_WD would return “= 10mm”). For digital parameters, VT_R4 variants
result in a state number and VT_BSTR variants result in a state string
(e.g. DP_RUNUPSTATE would return state 0 or “Shutdown” or the
equivalent in the language being supported). In C++, if the variant
type was specified as VT_BSTR then the API will internally allocate a
BSTR which the caller has to de-allocate using the SDK call
::SysFreeString (vValue.bstrVal)
Welcome to StackOverflow!
Well, each language is made with purpose. Then come to deal with ActiveX objects in browser (or WSH) environment, VBScript is the best choice, while JavaScript is most worst.
JavaScript hasn't so-called out parameters. That mean all function arguments are passed by value (as copy). Lets show you this with examples.
' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8
Sub Foo(ByVal arg1, ByRef arg2)
arg1 = 6
arg2 = 8
MsgBox "Local args: " & arg1 & ", " & arg2
End Sub
By default in VBS the arguments are passed by reference, so ByRef prefix in function arguments declaration is optional. I include it for clarity.
What the example illustrate is the meaning of "by reference" or "out" parameter. It behave like return value because it modify referenced variable. While modifying "by value" variable has no effect outside of the function scope, because we modify a "copy" of that variable.
// JavaScript
function foo(arg1) {
arg1 = 2;
alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);
// Local var = 2
// Outer var = 0
Now take a look at this thread. Looks like there is a kind of partial solution by using empty objects. I'm not sure in which cases that will work, but for sure it's very limited hack.
If this not help in your case, then looks like it's time to go with VBScript. Starting with VBS is easy anyway. It's the most user friendly language I ever touch. I was need days, even weeks with other languages only to get started, while just after a few hours with VBS I was able to use it freely.
[EDIT] Well, I made a lot more efforts to reply as may looks like at the glance :) Starting with the language limitation you met. Afterwards going to explain the nature of that limitation (what's "in/out" parameter), and the best way to do that is via example, and this is what I did. Afterwards I show you the only workaround out there to deal with this limitation in JS. Can we consider this as complete answer?
You not mention whether you test this "empty-object-trick", but as you still asking I presume you did that and it's not work with your OCX, right? Then, in this case, you're just forced to deal with your OCX via VBScript, what was my answer from the beginning. And as you prefer to stay with JS then you need to integrate a piece of VB code in your solution.
And as you noted too, this VBs/Js integration is a whole new question. Yes, good question of course, but it's a metter of new topic.
Ok, lets say that the question you append below: "why it should work with passing objects as a function parameter", is still a part of the main question. Well, as you see, even people using JS daily (am not one of them) has no idea what happens "behind the hood", i.e. do not expect an answer on what the JS-engine do in this case, or how this cheat the JS-engine to do something that it's not designed to do. Personally, as I use JS very rarely and not for such tasks, am not even sure if this trick works at all. But as the JS-guys assert it works (in some cases) then we s'd trust them. But that's all about. If this approach fail then it's not an option.
Now what's remain is a bit of homework, you s'd research all available methods for VBs/Js integration, also test them to see which one is most applicable to your domain, and if by chance you meet with difficulties, just then come-back to the forum with new topic and the concrete issue you're trying to resolve.
And to become as helpful as possible, I'll facilitate you with several references to get started.
Here is the plan...
1. If it's possible to work without VBs/Js integration then use stay-alone .VBS files (in WSH environment), else ...
2. In case you work in browser environment (HTML or HTA) then you can embed both (VBs/Js), and your integration w'd be simple.
3. Or may integrate VBs/Js with Windows Script Files (.wsf).
4. Or use ScriptControl that allow running VBScript from within JScript (or backward/opposite).
Links:
Using the ScriptControl
How To Call Functions Using the Script Control
An example VBs/Js integration using ScriptControl via
Batch-Embeded-Script
What is Batch-Embeded-Script:
VBS/Batch Hybrid
JS/Batch Hybrid
5. Some other method (if you find, that am not aware of).
Well, after all this improvements I not see what I can append more, and as I think, now
my answer is more than complete. If you agree with my answer then accept it by clicking on the big white arrow. Of course, if you expect to get better reply from other users, you may still wait, but keep in mind that unanswered questions stay active just for awhile and then become closed.

Differences between MongoDB Shell Scripting and JavaScript?

Since this is for a homework assignment I do not want to post my code because it essentially gives a solution. I can post some generic snippets. I am going to start off by saying I am new to javascript and Mongo, and basically learned them in a few hours last night.
Basically I have code that when I paste into the shell, it works perfectly, but when I save it into the database and try to execute it does not work. Here is a basic example.
db.system.js.save(
{
_id: "istrue",
value: function (x){
if(x == true)
print("true");
else
print("false");
}
})
So if I copy and paste this code and set var x = true or var x = false first then it works, but if I do this:
db.eval("istrue(true);");
Then it doesn't work.
Any ideas?
I can't find any documentation on this behavior, but a little testing reveals that your code is running just fine, but either stored functions can't use print or the output of print goes somewhere other than stdout. If you return strings instead of printing them, you'll see what you would expect.
I suspect the output is going to the MongoDB logs, but I'm not sure where my install put them.

Categories