/**
* Creates or opens a JSON-DB database at the given root directory.
*
* @constructor
* @param {String} rootPath Root of the JsonDB file hierarchy. The path must be a path within CompleteFTP's
* virtual file-system (e.g. /databases).
*
* @classdesc
* Provides access to JSON-DB databases. A JSON-DB database is a file-based object database where
* objects are stored in JSON files. JSON files may be arranged in an arbitrary directory hierarchy
* under a single 'root' directory. Though this class allows files to be written using the
* {@link JsonDB#write write}
* method, any other means of writing files from within CompleteFTP or externally may also be used.
* Objects in a JSON-DB database are accessed via an 'object-path'.
*
* The object-path in JSON-DB is analogous to a primary key in relational databases in the sense that
* it uniquely defines a single entity. It's more powerful than a primary key though since it
* facilitates hierarchical structuring of data like a traditional file-system. An object path consists of a
* file-path (with slash as a delimiter) and an optional object-path (with dot as a delimiter).
* For example, if a JSON file called 'b.json' is placed in
* a directory 'a' under the root directory, and if that file defines an object with a property, 'c',
* then that property may be read using the object-path, 'a/b.c'. Notice that `/` separates the folder and
* the file, and `.` separates the file and the property.
*
* An existing JSON object may be updated using the {@link JsonDB#update update} method. Individual objects may be read
* from a JSON-DB via the {@link JsonDB#read read} method. More generic querying is supported via the {@link JsonDB#query query} method.
*
* Since JSON-DB uses a file-system for storage, non-JSON files may be stored in the database
* alongside JSON objects. The {@link JsonDB#writeText writeText} and {@link JsonDB#writeBase64 writeBase64} allows such files to be written
* using the same file-paths as JSON objects.
*
* References between objects in a JSON-DB database are done via string properties with the suffix,
* '_ref'. The value is the object-path of the referenced object. The {@link JsonDB#read read} method returns these
* properties as strings. The {@link JsonDB#dereference dereference} method may be used to resolve reference properties
* to the objects that they reference. The deferenced properties will have the name of the reference
* property with the '_ref' suffix removed.
*/
var JsonDB = function (rootPath) {
/**
* Reads the object at the given path from the database. The path may specify a directory of JSON
* files, a specific JSON file, or an property within the object defined in a JSON file. For
* example, the path 'a/b.c' will reference the property called 'c' within the file with the path
* 'a/b.json'.
*
* @method
* @param {String} objectPath Path of the object.
* @param {Boolean} [fullResult] Should a full result object be returned, or just the object that was read?
* Defaults to false.
* @return {Object} The object returned depends on the 'fullResult' argument. If fullresult is false then
* the object at the path will be returned or an exception will be thrown if no object is
* found. If fullResult is true then an object with the following properties will be returned:
* 'target' the object at the path or null if not found; 'containers' an array of objects above
* the target object in the object-path; 'path' the object path; 'error' the error that occurred
* (if any).
*/
this.read = function (objectPath, fullResult) { };
/**
* Returns an array of references to all JSON files matching the given file-path pattern. This method only
* lists files, so the pattern must not reference fields inside objects. Wildcards (i.e. * or ?) may be placed
* in any element of the file-path.
*
* @method
* @param {String} pattern File-path pattern optionally containing wildcards.
* @param {Boolean} [includeFolders] Folders are included in the list if `true` otherwise folders are excluded (the default).
* @return {String[]} Array containing all matches.
*/
this.list = function (pattern, includeFolders) { };
/**
* A JSON-DB may be queried using an object-path containing wild-cards and a comparison. For example,
* a JSON-DB has a directory called `products` that contains a set of product objects stored in JSON files
* whose names are the product IDs, and those objects have a property called `colour`. To query for a certain
* colour, the pattern would be `products/*.colour`. If we want to find all the green objects then
* we'd call the query method as follows: `myDb.query('products/*.colour', '=', 'green', 'string')`.
*
* The result may be obtained via the callback or the return value.
*
* @method
* @param {String} pattern Wildcard object-path.
* @param {String} comparer Comparison operator to use: `=`, `>`, `<`, `>=`, `<=`, `<>`, `like` or `between`.
* @param {Object} value Value to compare with. Normally this is a single value, but if the operator is
* `between` then `value` should be an array containing two values: `[minimum, maximum]`
* @param {String} type Type being queried for: `number`, `string` or `date`.
* @param {Function} [evaluator] Evaluation function. If this is defined then the value returned from
* the function is matched. The referenced object is passed as an argument to the evaluator function.
* The JSS API is not available and cannot be used inside the evaluator function.
* E.g. `function(obj) { return obj.height * obj.width; }`
* @param {Function} [callback] Callback function to call for each match found.
* @return {String[]} Array containing all matching object references.
*/
this.query = function (pattern, comparer, value, type, evaluator, callback) { };
/**
* Removes the object at the given path.
*
* @method
* @param {String} objectPath Path of the object.
*/
this.remove = function (objectPath) { };
/**
* Writes the object to a JSON file at the given file-path.
*
* @method
* @param {String} filePath Path of the file to be written. Note that this path must only specify
* the file and not any object within a file.
* @param {Object} object Object to be written.
*/
this.write = function (filePath, object) { };
/**
* Updates an object that already exists in the database using a callback method. The callback
* function takes a single argument, which is the object that was read from the database. This
* object may be modified within the callback. The file containing the object will be written
* back to the database after the callback function returns.
*
* @method
* @param {String} objectPath Path of object to be updated. This may specify a JSON file
* or an object within a file.
* @param {Function} callback Callback function that is called for the object.
*/
this.update = function () { };
/**
* Resolves reference properties to the objects that they reference. In this method, the JsonDB
* engine will go through all properties of the given object looking for references, i.e.
* string properties whose names end with `_ref`. For each one that it finds it will read the
* object with that reference from the database and add a property to the given object whose
* name is the same as the reference property, but with the `_ref` suffix removed. The original
* object is not modified.
*
* For example, if a database contains one object at `/companies/MyCompany` as follows:
* ```
* {
* "name": "MyCompany",
* "number": 123456
* }
* ```
* and another as `/people/JohnSmith` as follows:
* ```
* {
* "firstName": "John",
* "lastName": "Smith",
* "company_ref": "/companies/MyCompany"
* }
* ```
* then if `dereference` is called on `/people/JohnSmith` then it will return:
* ```
* {
* "firstName": "John",
* "lastName": "Smith",
* "company": {
* "name": "MyCompany",
* "number": 123456
* }
* }
* ```
*
* @method
* @param {Object} object Object to be dereferenced. This object is not modified.
* @return {Object} Object with all reference properties dereferenced.
*/
this.dereference = function (object) { };
/**
* Writes a text file at the given location (relative to the JSON-DB root).
*
* @method
* @param {String} filePath Path of the file to write the text to.
* @param {String} text Text to write.
*/
this.writeText = function (filePath, text) { };
/**
* Append text to a file at the given location (relative to the JSON-DB root).
*
* @method
* @param {String} filePath Path of the file to append the text to.
* @param {String} text Text to append.
*/
this.appendText = function (filePath, text) { };
/**
* Reads the text file at the given location and returns the content as a string.
*
* @method
* @param {String} filePath Path of the file to read.
* @return {String} Content of file
*/
this.readText = function (filePath) { };
/**
* Writes a binary file at the given location (relative to the JSON-DB root).
*
* @method
* @param {String} filePath Path of the file to write the binary data to.
* @param {String} base64 Base-64 encoded binary data to write.
*/
this.writeBase64 = function (filePath, base64) { };
/**
* Reads the binary file at the given location and returns the content as a base-64 encoded string.
*
* @method
* @param {String} filePath Path of the file to read.
* @return {String} Content of file as base-64
*/
this.readBase64 = function (filePath) { };
}