takorogo
Version:
Takorogo to JSON parser for Node.js
241 lines (233 loc) • 12.5 kB
HTML
<html>
<head>
<meta charset='UTF-8'>
<title>Node.js parser from Takorogo to JSON Schema</title>
<script src='../javascript/application.js'></script>
<script src='../javascript/search.js'></script>
<link rel='stylesheet' href='../stylesheets/application.css' type='text/css'>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'undefined']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div id='base' data-path='../'></div>
<div id='header'>
<div id='menu'>
<a href='../extra/README.md.html' title='Node Takorogo'>
Node Takorogo
</a>
»
<a href='../alphabetical_index.html' title='Index'>
Index
</a>
»
<span class='title'>README.md</span>
</div>
</div>
<div id='content'>
<nav class='toc'>
<p class='title'>
<a class='hide_toc' href='#'>
<strong>Table of Contents</strong>
</a>
<small>
(<a class='float_toc' href='#'>left</a>)
</small>
</p>
</nav>
<div id='filecontents'>
<h1 id="node-takorogo">node-takorogo</h1><p>Takorogo to JSON parser for Node.js</p><p><a href="http://travis-ci.org/takorogo/node-takorogo"><img src="https://travis-ci.org/takorogo/node-takorogo.svg" alt="build status"></a>
<a href="https://coveralls.io/r/takorogo/node-takorogo"><img src="https://img.shields.io/coveralls/takorogo/node-takorogo.svg" alt="Coverage Status"></a>
<a href="http://badge.fury.io/js/takorogo"><img src="https://badge.fury.io/js/takorogo.svg" alt="NPM version"></a>
<a href="https://david-dm.org/takorogo/node-takorogo"><img src="https://david-dm.org/takorogo/node-takorogo.svg" alt="Dependency Status"></a>
<a href="https://david-dm.org/takorogo/node-takorogo#info=devDependencies"><img src="https://david-dm.org/takorogo/node-takorogo/dev-status.svg" alt="devDependency Status"></a></p><h2 id="installation">Installation</h2><p>This module is installed via npm:</p><pre><code class="lang-bash">$ npm install takorogo
</code></pre>
<h2 id="example-usage">Example Usage</h2>
<pre><code class="lang-js">var takorogo = require('takorogo');
var rules = takorogo.parse('user <--[POSTED]-- :User');
</code></pre>
<h2 id="takorogo-syntax">Takorogo Syntax</h2><p>Takorogo uses relations to maps properties to nodes determined by classes and their indices. That's all.</p><h3 id="relations">Relations</h3><p>For example we have a tweet with embedded user object:</p><pre><code class="lang-javascript">var tweet = {
id: 481101713646960641
user: {
default_profile_image : false,
id : 119102990,
profile_background_image_url_https : "https://pbs.twimg.com/profile_background_images/444244318/16840333315.png",
verified : false,
/* ... */
}
}
</code></pre><p>In this case we can say that tweet posted by user:</p><pre><code class="lang-takorogo">--[POSTED_BY]--> user:User
</code></pre><p>Or that user posted a tweet:</p><pre><code class="lang-takorogo"><--[POSTED]-- user:User
</code></pre><p>Or user and tweet has a bidirectional relationship:</p><pre><code class="lang-takorogo"><--[POSTED|POSTED_BY]--> user:User
</code></pre><p>Where <code>user</code> is a property name that contains embedded object and <code>:User</code> is a name of a class.</p><p>You can specify what attribute will be stored in relation passing them to relation in parentheses:</p><pre><code class="lang-takorogo">--[PARTICIPATE_IN(score, wins)]--> game:Game
</code></pre><p>You can specify types for relation attributes:</p><pre><code class="lang-takorogo">--[PARTICIPATE_IN(score: Score, wins: Integer)]--> game:Game
</code></pre><p>Or even destructuring an array property:</p><pre><code class="lang-takorogo">entities.urls[] --[REFERS_TO(indices[first, last])]--> :Url
</code></pre><p>Attention. Currently only plain values are supported. </p><h3 id="relations-resolved-from-keys">Relations resolved from keys</h3><p>Sometimes your document just points to something via key. In this case you can specify how relation should be resolved.</p><pre><code class="lang-takorogo">in_reply_to_status_id_str => id_str <--[ REPLIED_WITH|REPLIED_TO ]--> in_reply_to:Tweet
</code></pre><p>In the last case <code>=></code> means that <code>in_reply_to_status_id_str</code> should be treated as an <code>id_str</code> key.</p><p>For compound keys you can use following syntax:</p><pre><code class="lang-takorogo">(longitude, latitude) => (x, y) --[ LOCATED ]--> location:Point
</code></pre>
<h3 id="attributes">Attributes</h3><p>Sometimes your document's structure doesn't fit plane key-value nature of node.
In this case you can specify properties by paths:</p><pre><code class="lang-takorogo">--[CITIZEN_OF]--> place.country:Country
</code></pre><p>If document's field doesn't match what you want to have in the target node you can rename it:</p><pre><code class="lang-takorogo">--[CITIZEN_OF]--> place.country => country:Country
</code></pre><p>You also can assign types to attributes (user-defined classes are also supported):</p><pre><code class="lang-takorogo">def :Person {
+ firstName :String
+ dateOfBirth :Date
}
</code></pre><p>Attention: attribute aliasing in types constraints are not supported yet.</p><h3 id="embedded-objects">Embedded objects</h3><p>Embedded objects are stored inside the node. Mechanism depends on graph database engine. </p><h3 id="links-anonymous-relations-">Links (anonymous relations)</h3><p>You can store unstructured embedded object as a link to node: </p><pre><code class="lang-takorogo">--> metadata
</code></pre><p>As for normal relations you can specify classes and arrays for links:</p><pre><code class="lang-gypher">--> tweet:Tweet
--> comments:Comment[]
</code></pre>
<h3 id="indices">Indices</h3><p>You can specify unique constraint: </p><pre><code class="lang-takorogo">UNIQUE(id)
</code></pre><p>Takorogo also handles compound constraints:</p><pre><code class="lang-takorogo">UNIQUE(firstName, lastName)
</code></pre>
<h3 id="classes-types">Classes & Types</h3><p>You can refer to already defined class or type by colon notation:</p><pre><code class="lang-takorogo">UNIQUE(id:Int)
--> tweet:Tweet
</code></pre><p>In case when you have a collection of instances you can use an array syntax:</p><pre><code class="lang-takorogo">--> comments:Comment[]
</code></pre><p>Unstructured arrays are also supported:</p><pre><code class="lang-takorogo">--> things[]
</code></pre>
<h4 id="class-definition">Class Definition</h4><p>To define class use <code>def</code> keyword:</p><pre><code class="lang-takorogo">def Tweet
</code></pre><p>You can specify primary key in parentheses:</p><pre><code class="lang-takorogo">def HashTag(text)
</code></pre><p>Compound indexes are also supported:</p><pre><code class="lang-takorogo">def Person(firstname, lastname)
</code></pre><p>And you can use paths to specify properties:</p><pre><code class="lang-takorogo">def Citizen(credentials.passport.number)
</code></pre><p>Sometimes your class's primary key is stored in array.
For example we have a location document with unique combinations of longitude and latitude stored in array.
For this cases you can write: </p><pre><code class="lang-takorogo">def Location(coordinates[longitude, latitude])
</code></pre>
<h4 id="complex-classes">Complex Classes</h4><p>You can define rules for complex classes in curly braces:</p><pre><code class="lang-takorogo">def User(passport.id) {
--[CHILD_OF]--> father:Person
--[REFERS_TO(indices[first, last])]--> entities.url.urls[]:Url
}
</code></pre>
<h4 id="enumerations">Enumerations</h4><p>You can define enumeration mappers for arrays of fixed length:</p><pre><code class="lang-takorogo">def Coordinates [ longitude, latitude ]
</code></pre><p>After array items specified we can treat it as a regular document:</p><pre><code class="lang-takorogo">def VendorCoordinates [ longitude, latitude, vendor ] {
UNIQUE(longitude, latitude, vendor.id)
--[PRODUCED_BY]--> vendor:Vendor
}
</code></pre>
<h3 id="inline-class-definition">Inline Class Definition</h3><p>Simple classes can be defined inside relation rules by appending class name with parentheses:</p><pre><code class="lang-takorogo">--[POPULATED_WITH]--> comment:Comment(id)
</code></pre><p>You can specify indices as in normal declaration: </p><pre><code class="lang-takorogo">--[REFERS_TO]--> urls:Url(url)[]
</code></pre><p>That will create a class <code>Url</code> with <code>url</code> as primary key and use it as a map for related nodes.</p><h3 id="comments">Comments</h3><p>Takorogo supports only one line comments (both <code>#</code> and <code>//</code>):</p><pre><code class="lang-takorogo"># JIRA task
def Task {
UNIQUE(id) // Primary key
--[BLOCKED_BY]-->blocker:Task
}
</code></pre>
<h2 id="examples">Examples</h2><p>The following Takorogo script describes tweet structure from Twitter Stream API: </p><pre><code class="lang-takorogo"># The whole tweet document returned by Twitter Stream API
def Tweet {
UNIQUE(id_str:String)
UNIQUE(id:Int)
+ location: String
<--[POSTED]-- user:User
--> metadata
<--[ REPLIED_WITH|REPLIED_TO ]--> in_reply_to_status_id_str => in_reply_to:Tweet
--[ REFERS_TO(indices[first, last]) ]--> entities.urls[]:Url
--[ HAS_TAG(indices[first, last]) ]--> entities.hashtags[]:HashTag(text)
--[ AT ]--> coordinates:Location
--[ ON ]--> geo:Location
--[ PLACED ]--> place:Place
}
# Just a point
def Coordinates [ longitude, latitude ] {
UNIQUE(longitude: Double, latitude: Double)
}
def Location(coordinates:Coordinates) // Simply a wrapper for coordinates
def Place {
--[ BOUNDED_BY ]--> bounding_box.coordinates => bounding_box:Coordinates[]
}
def User(id_str) {
--[REFERS_TO(indices[first, last])]--> entities.url.urls[]:Url
}
</code></pre>
<h2 id="browser">Browser</h2><p>Client versions of <code>node-takorogo</code> can be built from sources or can be found in <code>./client/</code> directory of NPM module.</p><h2 id="contribution">Contribution</h2><p>You can start from <a href="http://sitin.github.io/node-takorogo/">API docs</a>.</p><p>I will accept only changes covered by unit tests.</p><h2 id="road-map">Road map</h2>
<h3 id="support-indentation-for-class-rules">Support indentation for class rules</h3>
<pre><code class="lang-takorogo">def :Person
UNIQUE(passport.id)
--[CHILD_OF]--> father:Person
</code></pre>
<h3 id="add-attribute-rewrite-in-type-constraint-statements">Add attribute rewrite in type constraint statements</h3>
<pre><code class="lang-takorogo">def :Person {
+ name.first => firstName :String
}
</code></pre>
</div>
</div>
<div id='footer'>
October 13, 14 21:09:47 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>
2.0.9
✲
Press H to see the keyboard shortcuts
✲
<a href='http://twitter.com/netzpirat' target='_parent'>@netzpirat</a>
✲
<a href='http://twitter.com/_inossidabile' target='_parent'>@_inossidabile</a>
</div>
<iframe id='search_frame'></iframe>
<div id='fuzzySearch'>
<input type='text'>
<ol></ol>
</div>
<div id='help'>
<p>
Quickly fuzzy find classes, mixins, methods, file:
</p>
<ul>
<li>
<span>T</span>
Open fuzzy finder dialog
</li>
</ul>
<p>
Control the navigation frame:
</p>
<ul>
<li>
<span>L</span>
Toggle list view
</li>
<li>
<span>C</span>
Show class list
</li>
<li>
<span>I</span>
Show mixin list
</li>
<li>
<span>F</span>
Show file list
</li>
<li>
<span>M</span>
Show method list
</li>
<li>
<span>E</span>
Show extras list
</li>
</ul>
<p>
You can focus and blur the search input:
</p>
<ul>
<li>
<span>S</span>
Focus search input
</li>
<li>
<span>Esc</span>
Blur search input
</li>
</ul>
</div>
</body>
</html>