Skip to content

AtiX/fsgdb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fsgdb - File System Graph Database

Travis CI Status

fsgdb is a graph like database based on the file system. Based on a root folder (or node), you can create subfolders/subnodes and attach data to each node by creating paresable files in each directory.

By allowing to merge data from parent nodes (think of: having a "blog" folder/node which contains metadata about your blog, which is then merged with each blog-entry-folder/sub-node), you can store data efficiently and deduplicated while maintaining a clear folder structure that is easily editable with standard editors.

Supported Parsers

At the moment, the following parsers are supported:

  • markdown: Parses markdown (*.md) files and attaches the parsed HTML content to each node.markdown.<filename> = "<parsedMarkdown>"
  • yaml: Parses yaml (*.yml) files and attaches the parsed properties to each node.<filename> = { <parsedProperties> }, with the exception that the properties of the file metadata.yml are added directly to the node without the in-between <filename> object.
  • images: Parses jpeg (*.jpg) files, reads out exif information and creates (if configured with createThumbnails: true) thumbnails. Adds helper functions that return image/thumbnail data. Note that for generating thumbnails, GraphicsMagick/ImageMagick needs to be installed on the system.

Usage

Hint: although the examples here are written in coffeescript, the module works with javascript as well.

The database is initialized by specifying a root directory and the list of parsers to use. Then, the directory can be scanned and data loaded.

FileSystemGraphDatabase = require('fsgdb').FileSystemGraphDatabase
graph = new FileSystemGraphDatabase({ path: './sampleApp/sampleData'})
graph.registerParser('MarkdownParser')
graph.registerParser('YamlParser')
loadingPromise = graph.load()

Based on the graph, the root node can be accessed and the tree can be traversed.

loadingPromise.then (rootNode) ->
  # Check for a property
  boolean = rootNode.hasProperty('propertyName')
  
  # Get a property
  value = rootNode.getProperty('propertyName')
  
  # Merge properties with values from parents (useful for deduplication of common data)
  mergedProperties = rootNode.flattenProperties()
  
  # use on nodes with children
  allLeaves = rootNode.getAllLeaves()

Querying

Instead of walking manually through nodes, queries can be used to filter efficiently. Queries are chainable.

Query = require('fsgdb').Query

q = new Query(rootNode)

# The most basic method is the .filter method, which expects a callback.
# This callback should return true or false if the given node passes the filter or not
q = q.filter (properties, node) -> return true

# Helper functions to simplify querying

# Query all nodes that have a property which contains a certain element:
q = q.whichContains('tags', 'technology')

# Or check for the existence of a property
q = q.withProperty('markdown')

#...that also must have a certain value
q = q.withProperty('date', '2015-12-31')

# Results can be given either as the direct results nodes (where the individual nodes
# might have children with different properties that do not match
# the query when properties are flattened)
nodes = q.resultNodes()

# Or get the leaves (nodes without children) with flattened properties to directly continue working with the
# combined data
nodes = q.resultLeaves()