In apstrata, data and digital assets are grouped into Documents, where each Document corresponds to a collection of name-value pairs known as fields. Each field within a Document has a type and can be specified to be indexed for full text searching.
In addition to the data itself, a Document contains metadata information such as the creator, creation time, last modification time, etc.
Documents may have Schemas defining their structure, in a declarative way, in terms of field groups, field types, field validations and field groups ACLs. Apstrata does not enforce the use of Schemas when persisting Documents. However, in this case, no security or validation rules can be applied at the level of the fields.
Each Document is persisted in a Store with a key that uniquely identifies it within that Store.
All Documents saved in an apstrata Store are secured individually with ACLs (from wikipedia: Access Control Lists), allowing developers to specify the Users and/or Groups that can view, update or delete a Document, or more granularly individual fields within that Document.
A developer can create as many Documents as needed per Store. However, there is a limit on the number of fields a Document can have, as well as on the size of digital assets within that Document. This limit is based on the apstrata account type that a developer has.
A developer can choose to create multiple versions of a certain Document. Each Document version is identified by a number which is automatically assigned to it upon creation time. This number is equivalent to the last version number of the Document plus one. At any point in time, a developer can retrieve a particular version of a Document. However, only the latest version of a Document can be updated. Reverting back to an old version of a Document simply means creating a new version with the data retrieved from that old version.
Document XML schema definition
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="schema"> <xs:annotation> <xs:documentation>Root element</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="aclGroups"> <xs:annotation> <xs:documentation>Groups all the security and validation checks</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="aclGroup" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>If this is ommitted, the security for all fields will be set to nobody</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="read" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default read permissions associated with this section. If no element is defined, the ACL value is 'nobody'.Possible values are: 1 - nobody, for denying access to all 2 - all, for granting access to all 3 - user or group:groupName or semi-colon separated users</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="write" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default write permissions associated with this section. If no element is defined, the ACL value is 'nobody'.Possible values are: 1 - nobody, for denying access to all 2 - all, for granting access to all 3 - user or group:groupName or semi-colon separated users</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="fields" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="field" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>Fields to which the security in this acl group apply</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="name" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:pattern value="[0-9A-Za-z_-]{1,32}"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="defaultAcl" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="read" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default read permissions associated with this section. If no element is defined, the ACL value is 'nobody'.Possible values are: 1 - nobody, for denying access to all 2 - all, for granting access to all 3 - user or group:groupName or semi-colon separated users</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="write" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default write permissions associated with this section. If no element is defined, the ACL value is 'nobody'.Possible values are: 1 - nobody, for denying access to all 2 - all, for granting access to all 3 - user or group:groupName or semi-colon separated users</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="delete" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default global delete permissions associated with this section. </xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="create" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the default global create permissions associated with this section. </xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="schemaAcl" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="read" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the users or groups that can read the schema</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="write" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the users or groups that can write the schema. Users can be separated by a semicolon. EX: user1;user2;user3;group:group1;group2;user4</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="delete" minOccurs="0"> <xs:annotation> <xs:documentation>This defines the users or groups that can delete the schema.</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="fields"> <xs:annotation> <xs:documentation>Contains all the document fields</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="field" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation> searchable: specifies if field is indexed for full text search unique: ensures only unique values for the given field within the set of all documents of the same schema type in a given store </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="validation" minOccurs="0"> <xs:annotation> <xs:documentation>Sets four types field level validation</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="cardinality" minOccurs="0"> <xs:annotation> <xs:documentation>Number of field occurrence in document.1 means mandatory = true </xs:documentation> </xs:annotation> <xs:complexType> <xs:attribute name="max" use="optional"> <xs:simpleType> <xs:restriction base="xs:int"/> </xs:simpleType> </xs:attribute> <xs:attribute name="min" use="optional"> <xs:simpleType> <xs:restriction base="xs:int"/> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="regex" minOccurs="0"> <xs:annotation> <xs:documentation>Validation regex</xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="range" minOccurs="0"> <xs:annotation> <xs:documentation>Min or max values</xs:documentation> </xs:annotation> <xs:complexType> <xs:attribute name="max" use="optional"> <xs:simpleType> <xs:restriction base="xs:float"/> </xs:simpleType> </xs:attribute> <xs:attribute name="min" use="optional"> <xs:simpleType> <xs:restriction base="xs:float"/> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="searchable" type="xs:boolean" use="optional" default="false"/> <xs:attribute name="name" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="1"/> <xs:pattern value="([A-Za-z_][0-9A-Za-z-_]{0,127})"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="type" use="optional" default="string"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="string"/> <xs:enumeration value="date"/> <xs:enumeration value="file"/> <xs:enumeration value="numeric"/> <xs:enumeration value="text"/> <xs:enumeration value="geospatial"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="maxSizeMB" type="xs:positiveInteger" use="optional" > <xs:annotation> <xs:documentation> <![CDATA[ This element becomes relevant only when defining a field of type file. It allows specifying a maximum file size for this specific field. Files larger than this may not be attached. This element cannot override the maximum file size per document. ]]> </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="unique" type="xs:boolean" use="optional" default="false"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="versioning" use="optional" default="disabled"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="disabled"/> <xs:enumeration value="enabled"/> <xs:enumeration value="forced"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>
Partial Document XML Schema Example
<schema> <aclGroups> <aclGroup name="admin"> <read>userA</read> <write>userB</write> <fields> <field>fieldone</field> </fields> </aclGroup> <aclGroup name="users"> <read>userC</read> <write>userD</write> <fields> <field>fieldtwo</field> </fields> </aclGroup> <defaultAcl> <read>userA</read> <write>userB</write> <delete>userC</delete> </defaultAcl> </aclGroups> <fields> <field name="fieldone" unique="true"> <validation> <regex>---regex validation---</regex> </validation> </field> <field name="fieldtwo" type="numeric" searchable="true"> <validation> <regex>thereg2</regex> <cardinality min="1" max="3"></cardinality> <range min="1" max="3"></range> </validation> </field> </fields> </schema>
Complete Document Schema Example
<schema versioning="enabled"> <aclGroups> <aclGroup name="editors"> <read>all</read> <write>group:editors;group:admins</write> <fields> <field>blogPost</field> <field>attachment</field> </fields> </aclGroup> <aclGroup name="public"> <read>all</read> <write>all</write> <fields> <field>comments</field> <field>commentor</field> <field>yourCoordinates</field> </fields> </aclGroup> <aclGroup name="status"> <read>all</read> <write>nobody</write> <fields> <field>postDate</field> <field>postCount</field> </fields> </aclGroup> <aclGroup name="restricted"> <read>group:admins</read> <write>group:admins</write> <fields> <field>score</field> <field>secretComments</field> </fields> </aclGroup> <defaultAcl> <read>all</read> <write>group:admins;joe;sam</write> <delete>group:admins</delete> </defaultAcl> <schemaAcl> <read>group:admins</read> <write>group:admins</write> <delete>group:admins</delete> </schemaAcl> </aclGroups> <fields> <field name="blogPost" searchable="true" type="text"> <validation> <cardinality min="1" max="1" /> </validation> </field> <field name="attachment" type="file" maxSizeMB="3"/> <field name="postDate" type="date" /> <field name="postCount" type="numeric" /> <field name="comments" type="text" unique="true"/> <field name="commentor" type="string" searchable="true"> <validation> <regex>^([a-zA-Z0-9@*#]{8,15})$</regex> </validation> </field> <field name="score" type="numeric"> <validation> <range min="1" max="10" /> </validation> </field> <field name="secretComments" type="text" /> <field name="yourCoordinates" type="geospatial" /> </fields> </schema>