2020-03-15 16:51:13 +00:00
|
|
|
module Pigeon
|
2020-04-15 13:00:11 +00:00
|
|
|
class Database
|
2020-04-16 14:05:10 +00:00
|
|
|
attr_reader :local_identity
|
|
|
|
|
2020-04-18 15:30:35 +00:00
|
|
|
def initialize(path: PIGEON_DB_PATH)
|
2020-04-16 14:05:10 +00:00
|
|
|
@store = Pigeon::Storage.new(path: path)
|
2020-04-18 15:51:08 +00:00
|
|
|
init_ident
|
2020-04-16 14:05:10 +00:00
|
|
|
end
|
|
|
|
|
2020-04-19 15:26:21 +00:00
|
|
|
# === PEERS
|
2020-04-18 15:30:35 +00:00
|
|
|
def add_peer(p); store.add_peer(p); end
|
|
|
|
def block_peer(p); store.block_peer(p); end
|
2020-04-19 15:26:21 +00:00
|
|
|
def remove_peer(p); store.remove_peer(p); end
|
2020-04-20 02:32:37 +00:00
|
|
|
def peer_blocked?(p); store.peer_blocked?(p); end
|
|
|
|
def all_blocks(); store.all_blocks(); end
|
|
|
|
def all_peers(); store.all_peers(); end
|
2020-04-19 15:26:21 +00:00
|
|
|
|
|
|
|
# === MESSAGES
|
2020-04-19 15:16:06 +00:00
|
|
|
def find_all_messages(mhash = nil); store.find_all_messages(mhash); end
|
2020-04-20 02:32:37 +00:00
|
|
|
def message_saved?(multihash); store.message_saved?(multihash); end
|
2020-04-18 14:59:56 +00:00
|
|
|
|
|
|
|
def save_message(msg_obj)
|
|
|
|
store.insert_message(Helpers.verify_message(self, msg_obj))
|
|
|
|
end
|
|
|
|
|
2020-04-17 13:55:18 +00:00
|
|
|
def read_message(multihash); store.read_message(multihash); end
|
|
|
|
|
|
|
|
def get_message_count_for(multihash)
|
|
|
|
store.get_message_count_for(multihash)
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_message_by_depth(multihash, depth)
|
|
|
|
store.get_message_by_depth(multihash, depth)
|
|
|
|
end
|
2020-04-16 14:05:10 +00:00
|
|
|
|
|
|
|
def create_message(kind, params)
|
2020-04-19 21:27:09 +00:00
|
|
|
publish_draft(new_draft(kind: kind, body: params))
|
2020-04-15 13:00:11 +00:00
|
|
|
end
|
|
|
|
|
2020-04-19 15:26:21 +00:00
|
|
|
# Store a message that someone (not the LocalIdentity)
|
|
|
|
# has authored.
|
|
|
|
def ingest_message(author:,
|
|
|
|
body:,
|
|
|
|
depth:,
|
|
|
|
kind:,
|
|
|
|
lipmaa:,
|
|
|
|
prev:,
|
|
|
|
signature:)
|
|
|
|
msg = Message.new(author: RemoteIdentity.new(author),
|
|
|
|
kind: kind,
|
|
|
|
body: body,
|
|
|
|
prev: prev,
|
|
|
|
lipmaa: lipmaa,
|
|
|
|
signature: signature,
|
|
|
|
depth: depth)
|
|
|
|
save_message(msg)
|
2020-03-15 16:51:13 +00:00
|
|
|
end
|
|
|
|
|
2020-04-19 15:26:21 +00:00
|
|
|
# === DRAFTS
|
|
|
|
def reset_current_draft; set_config(CURRENT_DRAFT, nil); end
|
2020-04-16 14:05:10 +00:00
|
|
|
|
2020-04-19 21:27:09 +00:00
|
|
|
def new_draft(kind:, body: {})
|
|
|
|
old = get_config(CURRENT_DRAFT)
|
|
|
|
if old
|
|
|
|
raise "PUBLISH OR RESET CURRENT DRAFT (#{old.kind}) FIRST"
|
|
|
|
end
|
|
|
|
save_draft(Draft.new(kind: kind, body: body))
|
2020-04-16 14:05:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def save_draft(draft)
|
|
|
|
set_config(CURRENT_DRAFT, draft)
|
|
|
|
draft
|
|
|
|
end
|
|
|
|
|
|
|
|
def current_draft
|
2020-04-19 21:27:09 +00:00
|
|
|
draft = store.get_config(CURRENT_DRAFT)
|
|
|
|
if draft
|
|
|
|
return draft
|
|
|
|
else
|
|
|
|
raise "THERE IS NO DRAFT. CREATE ONE FIRST."
|
|
|
|
end
|
2020-04-16 14:05:10 +00:00
|
|
|
end
|
|
|
|
|
2020-04-19 21:27:09 +00:00
|
|
|
def update_draft(k, v); Helpers.update_draft(self, k, v); end
|
|
|
|
|
|
|
|
def reset_draft
|
2020-04-18 14:13:53 +00:00
|
|
|
set_config(CURRENT_DRAFT, nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Author a new message.
|
2020-04-19 21:27:09 +00:00
|
|
|
def publish_draft(draft = self.current_draft)
|
2020-04-18 14:13:53 +00:00
|
|
|
Helpers.publish_draft(self, draft)
|
|
|
|
end
|
|
|
|
|
2020-04-19 15:26:21 +00:00
|
|
|
# === BUNDLES
|
|
|
|
def create_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
|
|
|
content = store
|
|
|
|
.find_all_messages(local_identity.multihash)
|
|
|
|
.map { |multihash| store.read_message(multihash) }
|
|
|
|
.sort_by(&:depth)
|
|
|
|
.map { |message| message.render }
|
|
|
|
.join(BUNDLE_MESSAGE_SEPARATOR)
|
|
|
|
File.write(file_path, content + CR)
|
|
|
|
end
|
|
|
|
|
|
|
|
def ingest_bundle(file_path = DEFAULT_BUNDLE_PATH)
|
|
|
|
bundle = File.read(file_path)
|
|
|
|
tokens = Pigeon::Lexer.tokenize(bundle)
|
|
|
|
Pigeon::Parser.parse(self, tokens)
|
2020-04-18 14:37:43 +00:00
|
|
|
end
|
|
|
|
|
2020-04-19 15:26:21 +00:00
|
|
|
# === BLOBS
|
|
|
|
def get_blob(b); store.get_blob(b); end
|
|
|
|
def put_blob(b); store.put_blob(b); end
|
|
|
|
|
|
|
|
# === DB Management
|
|
|
|
def get_config(k); store.get_config(k); end
|
|
|
|
def set_config(k, v); store.set_config(k, v); end
|
|
|
|
def reset_database; store.reset; init_ident; end
|
|
|
|
|
2020-04-16 14:05:10 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
attr_reader :store
|
|
|
|
|
2020-04-18 15:30:35 +00:00
|
|
|
def init_ident
|
|
|
|
secret = get_config(SEED_CONFIG_KEY)
|
|
|
|
if secret
|
|
|
|
@local_identity = LocalIdentity.new(secret)
|
2020-04-16 14:05:10 +00:00
|
|
|
else
|
2020-04-18 15:30:35 +00:00
|
|
|
new_seed = SecureRandom.random_bytes(Ed25519::KEY_SIZE)
|
2020-04-16 14:05:10 +00:00
|
|
|
set_config(SEED_CONFIG_KEY, new_seed)
|
2020-04-18 15:30:35 +00:00
|
|
|
@local_identity = LocalIdentity.new(new_seed)
|
2020-04-16 14:05:10 +00:00
|
|
|
end
|
|
|
|
end
|
2020-03-15 16:51:13 +00:00
|
|
|
end
|
|
|
|
end
|