[Bps-public-commit] Prophet branch, master, updated. 1507791d5f7721a11a8b05118a32895f4fe0e599

jesse jesse at bestpractical.com
Thu Feb 26 23:27:28 EST 2009


The branch, master has been updated
       via  1507791d5f7721a11a8b05118a32895f4fe0e599 (commit)
       via  3ed886e1e1693f9f874f6e5ebfd5bf072ce68079 (commit)
       via  06db7e620f23c91749ee16b07e7269e115afbb66 (commit)
       via  802ab4e2ad25f91b4dbc86fbf7052c3340058e67 (commit)
       via  6ee47fabca3c4b17fc273882f51721a6c7ebbf6d (commit)
       via  619749c8520de0538d430cd021a19970eb37b263 (commit)
       via  4726e4ea241140f1d89db98b93054d312a2071e6 (commit)
      from  447099d131c3a6956051117395c38132095f622f (commit)

Summary of changes:
 lib/Prophet/Manual.pod |  183 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 lib/Prophet/Manual.pod

- Log -----------------------------------------------------------------
commit 4726e4ea241140f1d89db98b93054d312a2071e6
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Wed Feb 25 06:00:30 2009 +0800

    Starting Prophet/Manual.pod
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
new file mode 100644
index 0000000..ea377dc
--- /dev/null
+++ b/lib/Prophet/Manual.pod
@@ -0,0 +1,28 @@
+=pod
+
+=head1 NAME
+
+Prophet::Manual - How Prophet works and how to use it
+
+=head1 Introduction
+
+A Prophet database is composed of records, each of which has several properties. Two core record properties
+are C<type> and C<uuid>. A record's C<type> indicates the kind of record (comment, ticket, user, etc.) and the
+C<uuid> of the record uniquely identifies it so that it can be referenced elsewhere. Another core property is a record's C<luid>
+which is a shorthand identifier used for local identification. For example:
+
+    # Instead of specifying the uuid
+    ticket show e4e5f9d8-ff7a-40c1-8c7f-2d6fcdd859ed
+
+    # ...you can use the luid
+    ticket show 9
+
+=head1 Glossary
+
+=head2 Record
+
+=head2 Property
+
+=head1 FAQ
+
+=cut

commit 619749c8520de0538d430cd021a19970eb37b263
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Wed Feb 25 06:09:45 2009 +0800

    Added syncwith.us introduction to Manual.pod
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
index ea377dc..26ae119 100644
--- a/lib/Prophet/Manual.pod
+++ b/lib/Prophet/Manual.pod
@@ -2,13 +2,25 @@
 
 =head1 NAME
 
-Prophet::Manual - How Prophet works and how to use it
+Prophet::Manual - What Prophet is, how it works and how to use it
 
 =head1 Introduction
 
-A Prophet database is composed of records, each of which has several properties. Two core record properties
+=head2 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: L<http://www.slideshare.net/obrajesse/web-20-is-sharecropping>
+
+=head2 How does it work?
+
+A Prophet database is composed of records, each of which has several properties. Two core properties
 are C<type> and C<uuid>. A record's C<type> indicates the kind of record (comment, ticket, user, etc.) and the
-C<uuid> of the record uniquely identifies it so that it can be referenced elsewhere. Another core property is a record's C<luid>
+C<uuid> of the record uniquely identifies it so that it can be referenced elsewhere. Another core property is a record's C<luid>,
 which is a shorthand identifier used for local identification. For example:
 
     # Instead of specifying the uuid

commit 6ee47fabca3c4b17fc273882f51721a6c7ebbf6d
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Wed Feb 25 07:34:03 2009 +0800

    Updated the FAQ
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
index 26ae119..0920ba4 100644
--- a/lib/Prophet/Manual.pod
+++ b/lib/Prophet/Manual.pod
@@ -1,5 +1,3 @@
-=pod
-
 =head1 NAME
 
 Prophet::Manual - What Prophet is, how it works and how to use it
@@ -8,7 +6,7 @@ Prophet::Manual - What Prophet is, how it works and how to use it
 
 =head2 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 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:
 
@@ -37,4 +35,12 @@ which is a shorthand identifier used for local identification. For example:
 
 =head1 FAQ
 
+=head2 Why doesn't Prophet use git or svn to track changes?
+
+The short answer: "The way you want to handle changes in a B<code>base (for source code) are very different than the way you want to handle changes in a B<data>base (for records and properties)"
+
+=head2 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 possibility
+
 =cut

commit 802ab4e2ad25f91b4dbc86fbf7052c3340058e67
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Thu Feb 26 05:10:40 2009 +0800

    Dox: Instantiating, loading, and saving the record object
    Dox: Database, replica, app_handle, handle
    Dox: Google Gears & Adobe Air
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
index 0920ba4..7b6eab5 100644
--- a/lib/Prophet/Manual.pod
+++ b/lib/Prophet/Manual.pod
@@ -27,12 +27,40 @@ which is a shorthand identifier used for local identification. For example:
     # ...you can use the luid
     ticket show 9
 
+=head2 Record overview
+
+=head3 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 L<Prophet::Record>, but designating a custom class, one that extends from L<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.
+
+=head3 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.
+
+=head3 Saving a record from the database
+
+There is no save method corresponding to load. Properties are immediately saved to the replica once they are set.
+
+Currently, the record object does not actually store any data. Rather, it acts as a proxy to the replica. This means that everytime you set a property, the entire record is diffed against the most recent version in the replica.
+
+=head2 Property overview
+
 =head1 Glossary
 
 =head2 Record
 
 =head2 Property
 
+=head2 Database
+
+The global state of all the data. The latest data that Alice and Bob have committed are in the database.
+
+=head2 Replica
+
+The local state of all the data. Alice keeps her most recent fetch of the database in her replica.
+
 =head1 FAQ
 
 =head2 Why doesn't Prophet use git or svn to track changes?
@@ -43,4 +71,20 @@ The short answer: "The way you want to handle changes in a B<code>base (for sour
 
 No it does not... yet. However, the conflict resolution in Prophet is pluggable, so it's a possibility
 
+=head2 What do C<app_handle> and C<handle> refer to? What is the difference between them?
+
+C<app_handle> is a reference to your application object, like an instance of C<MyApp.pm> that extends from C<Prophet::App>
+
+If you're familliar with Catalyst, you'll recognize it as being similar to the C<$catalyst> instance
+
+C<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 C<< DBI->connect >>
+
+=head2 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>
+
 =cut

commit 06db7e620f23c91749ee16b07e7269e115afbb66
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Thu Feb 26 06:53:51 2009 +0800

    More Manual.pod shenanigans
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
index 7b6eab5..73cf1c7 100644
--- a/lib/Prophet/Manual.pod
+++ b/lib/Prophet/Manual.pod
@@ -16,6 +16,14 @@ Here is a slideshow describing why Prophet came about: L<http://www.slideshare.n
 
 =head2 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 C<type> and C<uuid>. A record's C<type> indicates the kind of record (comment, ticket, user, etc.) and the
 C<uuid> of the record uniquely identifies it so that it can be referenced elsewhere. Another core property is a record's C<luid>,
@@ -39,13 +47,31 @@ Once you have a record object configured with a type and uuid, you can load data
 
 Currently, the record object does not actually store any data. Rather, it acts as a proxy to the replica.
 
-=head3 Saving a record from the database
+=head3 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. If they 
+
 Currently, the record object does not actually store any data. Rather, it acts as a proxy to the replica. This means that everytime you set a property, the entire record is diffed against the most recent version in the replica.
 
-=head2 Property overview
+=head2 Definining a property
+
+=head2 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 more.
+
+Prophet knows how to canonicalize a property by looking for a C<canonical_prop_$prop> method in the record class. If it finds one, it will be pass the properties (not just the named property) through in the form of a hashref to be canonicalized.
+
+=head2 Property validation
+
+Property validation makes sure a property has a valid value before committing it to the replica.
+
+Prophet knows how to validate a property by looking for a C<validate_prop_$prop> method in the record class. If it finds one, it will be 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 (die).
+
+You can also ask Prophet to validate a property based on recommended values.
 
 =head1 Glossary
 
@@ -53,13 +79,11 @@ Currently, the record object does not actually store any data. Rather, it acts a
 
 =head2 Property
 
-=head2 Database
-
-The global state of all the data. The latest data that Alice and Bob have committed are in the database.
-
 =head2 Replica
 
+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.
 
 =head1 FAQ
 
@@ -88,3 +112,30 @@ While Gears and Air allow you to take cloud applications offline, they don't sol
 <Insert something here about Gears/Air being based in JavaScript/Flash and Prophet not having that limitation>
 
 =cut
+
+12:55 < grink> what is a good word for the datastore in Prophet? database? replica database?
+12:55 < Sartak> database is the global state, replica is the local state
+12:56 < Sartak> so you probably want just replica :)
+12:56 < grink> sweeeeet
+12:57  * grink edits out "storage-thingy"
+13:15 < obra> local replica == local copy of the database
+13:15 < obra> grink: sd is the main app on Prophet we're working on right now
+13:17 < grink> isn't local replica redundant then?
+13:18 < obra> not really
+13:18 < obra> EVERY copy is a replica
+13:18 < grink> or are you saying, "Alice's local state" and "Bob's local state"
+13:18 < obra> my local replica is the one I'm working from
+13:19 < grink> so the database is the theoretical merging of all the replicas, but no one would ever work from the "database"
+13:19 < grink> you always interface through a replica
+13:20 < obra> there isn't really "the database"
+13:20 < obra> database is a word that describes any/all replicas. 
+13:20 < obra> every replica shares the same database uuid
+13:20 < obra> so you don't merge your replica of the foo database into my replica of the bar database
+13:21 < obra> it's kind of like cylons
+13:21 < obra> there are many copies.
+13:21 < grink> lol
+13:21 < obra> they're sort of interchangable
+13:21 < obra> but each comes from the same prototype
+13:21 < obra> and clones of the same kind can get inside each others' heads much more easily
+13:21 < obra> (This is ~why SD's milestones are named for cylons)
+

commit 3ed886e1e1693f9f874f6e5ebfd5bf072ce68079
Author: robertkrimen <robertkrimen at gmail.com>
Date:   Thu Feb 26 07:58:47 2009 +0800

    Even more Manual.pod shenanigans
    
    Signed-off-by: Jesse Vincent <jesse at bestpractical.com>

diff --git a/lib/Prophet/Manual.pod b/lib/Prophet/Manual.pod
index 73cf1c7..55ea442 100644
--- a/lib/Prophet/Manual.pod
+++ b/lib/Prophet/Manual.pod
@@ -51,23 +51,55 @@ Currently, the record object does not actually store any data. Rather, it acts a
 
 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. If they 
+Before properties are sent to the replica, the record object is responsible for canonicalizing and validating them.
 
-Currently, the record object does not actually store any data. Rather, it acts as a proxy to the replica. This means that everytime you set a property, the entire record is diffed against the most recent version in the replica.
+=head2 Definining a property: declaring, defaulting, and recommending
 
-=head2 Definining a property
+You can declare properties for a record by defining a C<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 C<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 C<_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 );
+    }
 
 =head2 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 more.
 
-Prophet knows how to canonicalize a property by looking for a C<canonical_prop_$prop> method in the record class. If it finds one, it will be pass the properties (not just the named property) through in the form of a hashref to be canonicalized.
+Prophet knows how to canonicalize a property by looking for a C<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.
 
 =head2 Property validation
 
 Property validation makes sure a property has a valid value before committing it to the replica.
 
-Prophet knows how to validate a property by looking for a C<validate_prop_$prop> method in the record class. If it finds one, it will be pass the properties (not just the named property) through in the form of a hashref to be validated.
+Prophet knows how to validate a property by looking for a C<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 (die).
 
@@ -77,9 +109,17 @@ You can also ask Prophet to validate a property based on recommended values.
 
 =head2 Record
 
+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.
+
 =head2 Property
 
-=head2 Replica
+A property is a name/value pair associated with a record.
+
+=head2 Collection
+
+A collection is used to search for and operate on records matching certain criteria. 
+
+=head2 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.
@@ -95,7 +135,7 @@ The short answer: "The way you want to handle changes in a B<code>base (for sour
 
 No it does not... yet. However, the conflict resolution in Prophet is pluggable, so it's a possibility
 
-=head2 What do C<app_handle> and C<handle> refer to? What is the difference between them?
+=head2 What do C<app_handle> and C<handle> refer to? What's the difference between them?
 
 C<app_handle> is a reference to your application object, like an instance of C<MyApp.pm> that extends from C<Prophet::App>
 
@@ -111,6 +151,8 @@ While Gears and Air allow you to take cloud applications offline, they don't sol
 
 <Insert something here about Gears/Air being based in JavaScript/Flash and Prophet not having that limitation>
 
+=head2 How does Prophet ensure that synchronized/shared data is valid?
+
 =cut
 
 12:55 < grink> what is a good word for the datastore in Prophet? database? replica database?

commit 1507791d5f7721a11a8b05118a32895f4fe0e599
Merge: 447099d... 3ed886e...
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Thu Feb 26 23:27:23 2009 -0500

    Merge branch 'master' of git at github.com:obra/prophet


-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list