Skip to content

Instantly share code, notes, and snippets.

@townie
Last active August 29, 2015 14:14
Show Gist options
  • Save townie/d29f7c120f44d89445ea to your computer and use it in GitHub Desktop.
Save townie/d29f7c120f44d89445ea to your computer and use it in GitHub Desktop.
Neo4j google drive items hierachy
class ChildOf
include Neo4j::ActiveRel
from_class GoogleDriveItem
to_class GoogleDriveItem
type 'child_of'
property :since, type: Integer
validates_presence_of :since
end
class GoogleDriveItem
include Neo4j::ActiveNode
include Backupify::LoggerSupport
property :document_id, constraint: :unique
property :service_id, default: "foo1"
property :document_type, default: "foo2"
property :folder_ids, default: {"foo12324" =>"bar"}
property :title, default: "foo7"
property :size, default: "foo235678"
serialize :access_control_list
serialize :folder_ids
index :document_id
has_many :out, :parents, model_class: GoogleDriveItem, rel_class: ChildOf
def set_parent(parent, since)
ChildOf.create(from_node: self, to_node: parent, since: since)
end
def children(time=Time.now.to_i)
time.to_datetime.to_i unless time.is_a?(Integer)
candidates = query_as(:parent).match('parent<-[rel:child_of]-(child)').where("rel.since < #{time}").pluck(:rel)
rels = candidates.inject({}) do |hash,rel|
doc_id = rel.from_node.document_id
if hash.has_key?(doc_id) && (rel.since > hash[doc_id].since)
hash[doc_id] = rel
else
hash[doc_id] = rel
end
hash
end
rels.values.map(&:from_node)
end
def insert_into_graph
node = fetch_node_with_document_id
if node.nil?
self.save
node = self
else
node = transfer_attr(node,self)
end
parents = locate_parent_object(node)
parents.each do |parent|
node.set_parent(parent, Time.now.to_i)
end
node
end
def hierarchy(time=Time.now.to_i)
time = time.to_datetime.to_i unless time.is_a?(Integer)
h = children(time).inject({}) do |hash,child|
hash[child.title] = child.hierarchy(time)
hash
end
if h.empty?
document_id
else
h
end
end
private
def label_from_mime(node)
node.add_label(node.document_type)
end
def transfer_attr(to_node,from_node)
attrs = to_node.attributes.keys
attrs.each do |attr|
to_node[attr] = from_node[attr]
end
to_node.save
to_node
end
def fetch_node_with_document_id
GoogleDriveItem.find_by(:document_id => self.document_id)
end
def locate_parent_object(node)
parent_ids = node.folder_ids.try(:keys)
# returns only in case of my_drive
return [] if node.is_my_drive?
parents = parent_ids.map do |pid|
begin
GoogleDriveItem.find_by(:document_id => pid)
rescue => e
logger.log_exception(e)
end
end
parents.compact!
if parents.empty?
parents = create_dummy_parent(parent_ids)
end
parents
end
def create_dummy_parent(parent_ids)
parent_ids.map do |pid|
GoogleDriveItem.create(:document_id => pid)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment