class CouchDB::LocalReplica

Overview

A Database backed by a local SQLite file that continuously syncs with a remote CouchDB in both directions. All reads operate on the local store for low latency and offline capability.

Checkpoints are stored on the remote adapter only (_local/ documents), so the local file can be deleted and recreated without losing sync progress.

Two write modes are available:

Use Database.local_replica to create instances.

db = CouchDB::Database.local_replica("notes.db",
  "https://user:pass@mycouch.example.com/notes")
db.on_sync_error { |dir, ex| Log.error { "#{dir}: #{ex.message}" } }
db.put(note)     # writes locally; background push syncs to remote
db.get("note-1") # reads from local
db.close         # stops sync fibers, closes both adapters

Defined in:

couchdb/local_replica.cr

Constant Summary

SYNC_INITIAL_BACKOFF = 1.second
SYNC_MAX_BACKOFF = 60.seconds
UPSTREAM_WAIT_INTERVAL = 10.milliseconds
UPSTREAM_WAIT_TIMEOUT = 5000.milliseconds

Instance Method Summary

Instance methods inherited from class CouchDB::Database

adapter : Adapter adapter, all_docs(include_docs : Bool = false, limit : Int32 | Nil = nil, skip : Int32 = 0, startkey : String | Nil = nil, endkey : String | Nil = nil) : NamedTuple(total_rows: Int64, offset: Int32, rows: Array(JSON::Any))
all_docs(as klass : T.class, limit : Int32 | Nil = nil, skip : Int32 = 0, startkey : String | Nil = nil, endkey : String | Nil = nil) : NamedTuple(total_rows: Int64, offset: Int32, rows: Array(T)) forall T
all_docs
, bearer_token=(token : String) bearer_token=, bulk_docs(docs : Array(Document), new_edits : Bool = true) : Array(NamedTuple(id: String, rev: String, ok: Bool)) bulk_docs, bulk_get(id_revs : Array(NamedTuple(id: String, rev: String))) : Array(Document) bulk_get, changes(since : String = "0", limit : Int32 | Nil = nil, include_docs : Bool = false) : NamedTuple(last_seq: String, results: Array(JSON::Any)) changes, changes_feed(since : String = "0", heartbeat : Int32 = 1000, include_docs : Bool = false, & : JSON::Any -> _) changes_feed, close close, delete_attachment(id : String, attname : String, rev : String) : NamedTuple(ok: Bool, id: String, rev: String) delete_attachment, find(selector : JSON::Any, fields : Array(String) | Nil = nil, sort : Array(JSON::Any) | Nil = nil, limit : Int32 | Nil = nil, skip : Int32 = 0) : NamedTuple(docs: Array(JSON::Any), warning: String | Nil) find, get(id : String, as klass : T.class) : T forall T
get(id : String) : Document
get
, get_attachment(id : String, attname : String) : NamedTuple(data: Bytes, content_type: String) get_attachment, get_local(id : String) : Document get_local, info : NamedTuple(db_name: String, doc_count: Int64, update_seq: Int64) info, on_conflict(&block : Document, Document -> Document | Nil) on_conflict, on_remove_conflict(&block : Document, String -> Bool | Nil) on_remove_conflict, on_request(&block : ::HTTP::Request -> Nil) on_request, on_response(&block : ::HTTP::Client::Response -> ::HTTP::Client::Response) on_response, put(doc : Document) : NamedTuple(ok: Bool, id: String, rev: String) put, put_attachment(id : String, attname : String, rev : String, data : Bytes, content_type : String) : NamedTuple(ok: Bool, id: String, rev: String) put_attachment, put_local(doc : Document) : NamedTuple(ok: Bool, id: String, rev: String) put_local, query(key : JSON::Any | Nil = nil, keys : Array(JSON::Any) | Nil = nil, startkey : JSON::Any | Nil = nil, endkey : JSON::Any | Nil = nil, limit : Int32 | Nil = nil, skip : Int32 = 0, descending : Bool = false, include_docs : Bool = false, reduce : String | Nil = nil, group : Bool = false, group_level : Int32 | Nil = nil, &map : Document, Proc(JSON::Any | Nil, JSON::Any | Nil, Nil) -> _) : NamedTuple(total_rows: Int64, offset: Int32, rows: Array(JSON::Any)) query, remove(id : String, rev : String) : NamedTuple(ok: Bool) remove, replicate_from(source : Database, doc_ids : Array(String) | Nil = nil, selector : JSON::Any | Nil = nil, filter : Proc(Document, Bool) | Nil = nil) : Replication::Session replicate_from, replicate_to(target : Database, doc_ids : Array(String) | Nil = nil, selector : JSON::Any | Nil = nil, filter : Proc(Document, Bool) | Nil = nil) : Replication::Session replicate_to, revs_diff(id_revs : Hash(String, Array(String))) : Hash(String, NamedTuple(missing: Array(String))) revs_diff, sync(remote : Database, doc_ids : Array(String) | Nil = nil, selector : JSON::Any | Nil = nil, filter : Proc(Document, Bool) | Nil = nil) sync, tls=(ctx : OpenSSL::SSL::Context::Client) tls=

Constructor methods inherited from class CouchDB::Database

new(location : String)
new(adapter : Adapter)
new

Class methods inherited from class CouchDB::Database

local_replica(local_path : String, remote_url : String, heartbeat : Int32 = 2000, write_upstream : Bool = false, sync_initial_backoff : Time::Span = LocalReplica::SYNC_INITIAL_BACKOFF, sync_max_backoff : Time::Span = LocalReplica::SYNC_MAX_BACKOFF) : LocalReplica local_replica

Instance methods inherited from module CouchDB::Adapter

all_docs(include_docs : Bool, limit : Int32 | Nil, skip : Int32, startkey : String | Nil, endkey : String | Nil) : NamedTuple(total_rows: Int64, offset: Int32, rows: Array(JSON::Any)) all_docs, bulk_docs(docs : Array(Document), new_edits : Bool) : Array(NamedTuple(id: String, rev: String, ok: Bool)) bulk_docs, bulk_get(id_revs : Array(NamedTuple(id: String, rev: String))) : Array(Document) bulk_get, changes(since : String, limit : Int32 | Nil, include_docs : Bool) : NamedTuple(last_seq: String, results: Array(JSON::Any)) changes, changes_feed(since : String, heartbeat : Int32, include_docs : Bool, &block : JSON::Any -> _) changes_feed, close close, delete_attachment(id : String, attname : String, rev : String) : NamedTuple(ok: Bool, id: String, rev: String) delete_attachment, get(id : String) : Document get, get_attachment(id : String, attname : String) : NamedTuple(data: Bytes, content_type: String) get_attachment, get_local(id : String) : Document get_local, info : NamedTuple(db_name: String, doc_count: Int64, update_seq: Int64) info, put(doc : Document) : NamedTuple(ok: Bool, id: String, rev: String) put, put_attachment(id : String, attname : String, rev : String, data : Bytes, content_type : String) : NamedTuple(ok: Bool, id: String, rev: String) put_attachment, put_local(doc : Document) : NamedTuple(ok: Bool, id: String, rev: String) put_local, remove(id : String, rev : String) : NamedTuple(ok: Bool) remove, revs_diff(id_revs : Hash(String, Array(String))) : Hash(String, NamedTuple(missing: Array(String))) revs_diff

Instance Method Detail

def close #

Stops background sync fibers and closes both the local and remote adapters. Fibers complete their current in-progress replicate call before stopping.


[View source]
def on_sync_error(&block : String, Exception -> Nil) #

Registers a block called when a background sync run fails.


[View source]
def put(doc : Document) : NamedTuple(ok: Bool, id: String, rev: String) #

In upstream mode: writes to the remote and blocks until the change has replicated to local. In local mode: delegates to super (local SQLite).


[View source]
def remove(id : String, rev : String) : NamedTuple(ok: Bool) #

In upstream mode: removes on the remote and blocks until the tombstone has replicated to local. In local mode: delegates to super.


[View source]