Implementing a backend

hbons edited this page Jan 8, 2013 · 32 revisions

Implementing a backend

By default, SparkleShare uses Git to store and sync files. However, you can implement a custom backend to suit your needs with relative ease. It's possible to use an other version control system or some other custom protocol. This page tries to explain how to go about this.

Getting started

Put your files in SparkleLib/. You can create a subdirectory for your backend if you want (like the default backend Git/). Just make sure the files are added to the Makefile.am file for compilation.

It's important that your files and classes are named properly. For example: if your backend is called foo, then name your extended classes SparkleLib.Foo.SparkleRepo and SparkleLib.Foo.SparkleFetcher.

Overview

There are two abstract classes that need extending to get a working backend:

  • SparkleFetcherBase takes care of the initial fetching of a remote repository,
  • SparkleRepoBase implements the syncing algorithm and handles notifications between clients.

Here's an overview of all the members that need an implementation:

SparkleRepoBase

// Constructors
public SparkleRepoGit (string path);

// Methods
public abstract bool SyncUp ();
public abstract bool SyncDown ();
public abstract List<SparkleChangeSet> GetChangeSets (int count);
protected void OnProgressChanged (double progress_percentage, string progress_speed);

// Properties
public virtual string Identifier { get; }
public abstract string CurrentRevision { get; }
public abstract bool HasRemoteChanges { get; }
public abstract bool HasLocalChanges { get; }
public abstract double Size { get; }
public abstract double HistorySize { get; }

SparkleFetcherBase

// Constructors
public SparkleFetcherBase (string server, string remote_folder, string target_folder);

// Methods
public abstract bool Fetch ();
public abstract void Stop ();
protected void OnProgressChanged (double percentage);

// Properties
public string [] Warnings { get; }

Explanation of Class Members

SparkleRepoBase

Methods

public abstract bool SyncUp ();
// Sends changes to the remote repository
// Returns true on success, false on failure
// Git example: "git add -A", "git commit" and "git push"
public abstract bool SyncDown ();
// Gets changes from the remote repository
// Returns true on success, "false" on failure
// Git example: "git fetch", "git rebase" and resolve any conflicts
List<SparkleChangeSet> GetChangeSets (int count);
// Returns a list of SparkleChangeSet objects describing the history of the project, limited by a count
// Optional. Return null if your backend doesn't keep track of history
// Git example: parses "git log"
protected void OnProgressChanged (double progress_percentage, string progress_speed);
// Call this method from SyncUp () and SyncDown () when the syncing progresses
// This gives the frontend information about the progress. Optional

Properties

public abstract string Identifier { get; }
// A reasonably unique name/number/hash for a project. This identifier must be the same on every client
// You must return something even if your backend does not support history
// Git example: uses the first commit hash of the repository
public abstract string CurrentRevision { get; }
// A string representing the current revision of the project tree
// Git example: the hash of the last commit
public abstract bool HasRemoteChanges { get; }
// Whether there are remote changes that we don't have yet
// Git example: compares CurrentRevision with the remote hash retrieved with "git ls-remote"
public abstract bool HasLocalChanges { get; }
// Whether there are local changes that we haven't accounted for yet
// Git example: a "git status"
public abstract double Size { get; }
// The size of the current revision of the project in bytes
public abstract double HistorySize { get; }
// The size of the history of the project in bytes
// Git example: the size of the ".git" directory

SparkleFetcherBase

Methods

public abstract bool Fetch ();
// Fetches the remote repository
// Git example: a "git clone", plus some configuration
public abstract void Stop ();
// Stops the fetching process started by Fetch ()
protected void OnProgressChanged (double progress_percentage);
// Call this method from Fetch () when the syncing progresses
// This gives the frontend information about the progress. Optional

Properties

public string [] Warnings;
// If there's anything the user needs to be aware of, add it to this array

Notes

All implemented members need to be blocking/synchronous.

Testing

You can specify a backend type to use by prepending its name to the Address value in the Add Hosted Project dialog. For example:

  • ssh+git://sparkleshare.org/ uses the classes SparkleLib.Git.SparkleRepo, SparkleLib.Git.SparkleFetcher as its backend
  • ssh+hg://sparkleshare.org/ uses the classes SparkleLib.Hg.SparkleRepo, SparkleLib.Hg.SparkleFetcher as its backend

Click Add and if you did everything well, your repo should now be sparkling away! :)