Provided by: libprophet-perl_0.743-1_all bug


       Prophet::Manual - What Prophet is, how it works and how to use it


   What is Prophet?
       Prophet is a new kind of database designed for the post Web-2.0 world. It's made to let
       you collaborate with your friends and coworkers without needing any kind of special server
       or Internet provider.

       Prophet's buzzword-laden pitch reads something like this:

           A grounded, semirelational, peer to peer replicated, disconnected, versioned, property database with self-healing conflict resolution.

       Here is a slideshow describing why Prophet came about:

   How does it work?
       There are two ways to create a Prophet database: cloning and initing

       One way is to clone an existing database. When you clone an existing database, a local
       replica is created for you with the uuid of the cloned database.

       Another way is to init a database. This creates a database with a new uuid. Anyone who
       clones from this database will get a replica of the data and share the database uuid.

       Note that Prophet will prevent you from merging databases unless they have the same
       database uuid (although you can force the merge of different databases if you want).

       A Prophet database is composed of records, each of which has several properties. Two core
       properties are "type" and "uuid". A record's "type" indicates the kind of record (comment,
       ticket, user, etc.) and the "uuid" of the record uniquely identifies it so that it can be
       referenced elsewhere. Another core property is a record's "luid", which is a shorthand
       identifier used for local identification. For example:

           # Instead of specifying the uuid
           ticket show e4e5f9d8-ff7a-40c1-8c7f-2d6fcdd859ed

           # can use the luid
           ticket show 9

   Record overview
       The record object (Prophet::Record)

       A record object in Prophet is initially an empty husk. First, the record class is found.
       The default record class is Prophet::Record, but designating a custom class, one that
       extends from Prophet::Record is possible. Once the record class is found, the object is
       instantiated and passed the app_handle, handle, and type of the record. The record is now
       ready for use.

       Loading a record from the database

       Once you have a record object configured with a type and uuid, you can load data from the
       replica. This consists of asking the replica (handle) for the properties corresponding to
       the given record type and uuid.

       Currently, the record object does not actually store any data. Rather, it acts as a proxy
       to the replica.

       Saving a record to the database

       There is no save method corresponding to load. Properties are immediately saved to the
       replica once they are set.

       Before properties are sent to the replica, the record object is responsible for
       canonicalizing and validating them.

   Definining a property: declaring, defaulting, and recommending
       You can declare properties for a record by defining a "declared_props" routine for a
       record. The routine should return a list of properties declared for the record type. Don't
       forget to return inherited properties! Here is an example:

           sub declared_props {
               return ('email', shift->SUPER::declared_props(@_))

       Prophet knows how to default a property by looking for a "default_prop_$prop" method in
       the record class. If it finds one, it will pass the properties (not just the property to
       be defaulted) through in the form of a hashref. The returned value is the default value
       for the property. The default method is NOT triggered if the property value is already
       defined (not undef)

       Generating property defaults takes place during record creation.

       You can also recommend values for a property. Recommending values for a property is mainly
       used for validation. To recommend values for a property, define a
       "_recommended_values_for_prop_$prop" routine in your record class. The routine should
       return a list of which is the range of values for the property. Here is an example of how
       SD uses value recommending to validate:

           # A globally defined "statuses" setting is specified in App::SD
           sub database_settings {
               statuses => ['24183C4D-EFD0-4B16-A207-ED7598E875E6' => qw/new open stalled closed rejected/],


           # App::SD::Model::Ticket uses the "statuses" setting for recommended values
           sub _recommended_values_for_prop_status {
              return @{ shift->app_handle->setting( label => 'statuses' )->get() };


           # App::SD::Model::Ticket uses the recommended values for "status" to validate
           sub validate_prop_status {
               my ( $self, %args ) = @_;
               return $self->validate_prop_from_recommended_values( 'status', \%args );

   Property canonicalization
       Property canonicalization makes sure a property is in the right format. It includes
       trimmming leading and trailing whitespace, making sure text is in the right case, and

       Prophet knows how to canonicalize a property by looking for a "canonical_prop_$prop"
       method in the record class. If it finds one, it will pass the properties (not just the
       named property) through in the form of a hashref to be canonicalized.

   Property validation
       Property validation makes sure a property has a valid value before committing it to the

       Prophet knows how to validate a property by looking for a "validate_prop_$prop" method in
       the record class. If it finds one, it will pass the properties (not just the named
       property) through in the form of a hashref to be validated.

       If the validation routine makes note of an error, Prophet will abort with an exception

       You can also ask Prophet to validate a property based on recommended values.


       A record is a collection of properties (much like an SQL table is a collection of
       columns). A record must have a type and uuid. It may also have an luid, which is like a
       uuid but only valid for the local environment/replica.

       A property is a name/value pair associated with a record.

       A collection is used to search for and operate on records matching certain criteria.

   Replica (WIP)
       The database that a Prophet application works from.  The local state of all the data.
       Alice keeps her most recent fetch of the database in her replica.  The global state of all
       the data. The latest data that Alice and Bob have committed are in the database.


   Why doesn't Prophet use git or svn to track changes?
       The short answer: "The way you want to handle changes in a codebase (for source code) are
       very different than the way you want to handle changes in a database (for records and

   Does Prophet currently do sub-property (content-level) diffing?
       No it does not... yet. However, the conflict resolution in Prophet is pluggable, so it's a

   What do "app_handle" and "handle" refer to? What's the difference between them?
       "app_handle" is a reference to your application object, like an instance of ""
       that extends from "Prophet::App"

       If you're familliar with Catalyst, you'll recognize it as being similar to the $catalyst

       "handle" is a reference to your repository "database", depending on what kind of Replica
       you're using

       If you're familliar with DBI, you'll recognize it as the database handle that is returned
       when you connect to a database via "DBI->connect"

   How is Prophet different from something like Google Gears or Adobe Air?
       While Gears and Air allow you to take cloud applications offline, they don't solve the
       data merging/synchronization problem.

       <Insert something here about Gears/Air being based in JavaScript/Flash and Prophet not
       having that limitation>

   How does Prophet ensure that synchronized/shared data is valid?