Persevere offers very flexible storage of JSON objects. You can store schema-free JSON data if you like and optionally make use of a flexible schema system to ensure data integrity when that's desirable for your application.
ClassesPersevere stores objects by class. Class definitions and instances are accessible through URLs. There are several important URLs for accessing classes:
Creating New ClassesThere are several ways to define new classes:
Extending/Subclassing ClassesClasses, can "extend" other classes, meaning all instances of the subclass must be valid by any schema defined by the superclass, and will be members of the superclass. An instance of the subclass will exist in queries of both the superclass and subclass. However, direct instances of the superclass will not appear in the subclass.Subclassing also affects prototype chains - a subclass will have a prototype object that delegates to the prototype object of the superclass. In other words, If you define methods for the superclass's objects, those methods will be available on the subclass's objects as well (unless they are overridden). To extend another class, simply refer to the class with the extends property: MySuperClass = Class({ id:"MySuperClass", ... }); Class({ id:"MyClass", extends: MySuperClass .. }); Class DefinitionsIn Persevere, classes and their structure and methods are defined using JSON Schema which provide validation and integrity for persisted objects. Every class has a corresponding schema, which can be accessed at /Class/ClassName. The schema can be used to constrain property value types for all the object instances on a table. The schema also allow methods and method signatures to be defined that are available on all instances. See the JSON Schema documentation for more information.
A class schema can be accessed and edited both on the filesystem in the WEB-INF/config directory, and dynamically via HTTP POST.
QueryingPersevere implements an JSONQuery which extends JSONPath
and has been greatly expanded with numerous additional features for
more powerful querying capabilities. A JSONQuery starts with object
URL that is indicates the list being queried. JSONQuery can then be
used to find objects by different property values using various
operators. For example:
The JSONQuery documentation provides more in-depth description of the querying capabilities.
/Customer/?lastName='Smith' Persisting Methods/FunctionsIn Persevere, you can use functions like any other value and they can be stored in properties just like any other value as long as the object is backed by a store that supports functions, and the default dynamic object database in Persevere does support functions. Typically, you will want to add functions/methods to the prototype object for a class/table. For example you could create a method getFullName that is available for all Customer objects by sending: PUT /Customer.prototype HTTP/1.1 JavaScriptDBJavaScriptDB is Persevere's default storage engine. JavaScriptDB supports storing a wide array of data types and allows objects to be stored with any structure. JavaScriptDB records a full history of all object changes. Changes are made available in the Transaction table. Each Transaction instance corresponds to a successfully committed transaction, and holds the state of the objects that were changed.
By default JavaScriptDB writes data to the disk using standard writes, allowing the OS to use high-speed write-back caching. JavaScriptDB also supports high-integrity synchronized disk writes, for situations where transactions should be verified to be written to the disk before returning. High-integrity synchronized writes can be configured by setting the "sources":[ Generally, high-integrity writes are about 50% slower than normal writes. JavaScriptDB also automatically indexes properties on objects using adaptive and on-demand indexing with background processing. By default, when an object is changed (created, modified, or deleted) all properties of objects are set to be indexed in background process (so as not to slow down the transaction). If a large number of objects (greater than 2000) are created with a given property, and no queries are made against that query, JavaScriptDB will stop automatically indexing that property for each modification. However, if a query is made against that property in the future, JavaScriptDB will bring the index up to date at that point.
Indexing can also be manually controlled from schemas. Property definitions may include a schema: {
By default JavaScriptDB assigns numerical auto-incremented ids. However, you can also assign string ids to objects. JavaScriptDB can also be configured to assign UUIDs instead of incrementing numbers. To configure for UUID assignment, add a useUUIDs: true to the data source config: "sources":[ Resetting the DatabaseDuring development it may be useful to occasionally "reset" the database to the initial conditions. This can be done by deleting the directories within /WEB-INF/data. When these are deleted and Persevere is restarted, Persevere will automatically recreate the database to the initial state. |