xnlogic 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +43 -0
  7. data/bin/xnlogic +13 -0
  8. data/lib/xnlogic/cli/application.rb +60 -0
  9. data/lib/xnlogic/cli.rb +73 -0
  10. data/lib/xnlogic/friendly_errors.rb +50 -0
  11. data/lib/xnlogic/man/xnlogic +46 -0
  12. data/lib/xnlogic/man/xnlogic.txt +42 -0
  13. data/lib/xnlogic/templates/application/.rspec.tt +2 -0
  14. data/lib/xnlogic/templates/application/Gemfile.tt +6 -0
  15. data/lib/xnlogic/templates/application/Readme.md.tt +86 -0
  16. data/lib/xnlogic/templates/application/gitignore.tt +9 -0
  17. data/lib/xnlogic/templates/application/lib/fixtures/sample_fixtures.rb.tt +53 -0
  18. data/lib/xnlogic/templates/application/lib/gemname/fixtures.rb.tt +108 -0
  19. data/lib/xnlogic/templates/application/lib/gemname/initializers/inflections.rb.tt +13 -0
  20. data/lib/xnlogic/templates/application/lib/gemname/models.rb.tt +37 -0
  21. data/lib/xnlogic/templates/application/lib/gemname/parts/has_notes.rb.tt +10 -0
  22. data/lib/xnlogic/templates/application/lib/gemname/parts/note.rb.tt +41 -0
  23. data/lib/xnlogic/templates/application/lib/gemname/permissions.rb.tt +136 -0
  24. data/lib/xnlogic/templates/application/lib/gemname/type/url.rb.tt +13 -0
  25. data/lib/xnlogic/templates/application/lib/gemname/type.rb.tt +10 -0
  26. data/lib/xnlogic/templates/application/lib/gemname/version.rb.tt +3 -0
  27. data/lib/xnlogic/templates/application/lib/gemname.rb.tt +116 -0
  28. data/lib/xnlogic/templates/application/spec/gemname/gemname_spec.rb.tt +7 -0
  29. data/lib/xnlogic/templates/application/spec/spec_helper.rb.tt +44 -0
  30. data/lib/xnlogic/ui/shell.rb +96 -0
  31. data/lib/xnlogic/ui/silent.rb +45 -0
  32. data/lib/xnlogic/ui.rb +7 -0
  33. data/lib/xnlogic/version.rb +3 -0
  34. data/lib/xnlogic.rb +33 -0
  35. data/man/xnlogic.ronn +38 -0
  36. data/xnlogic.gemspec +27 -0
  37. metadata +149 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 228227d4a324ef82abaa6dee535286df33108c12
4
+ data.tar.gz: d9a430dbd6b9d08cc251c1a0264ed95fde17d765
5
+ SHA512:
6
+ metadata.gz: 644272798d732f21d5f1be96da46a14b3d70b5036ba2713460c8cb49404041a42a06b0148ef51fe51fa1c69bc5ee15134444e99557f2996566249857c128e56c
7
+ data.tar.gz: 7a87b081194d30a86f416f66fc9f0f7dd128d181600933f2974d9cce809169a4bfd7e18214f406bdf4a6ac1c70a94d600bf85584b4572f8b248ec1cd3a14bcaa
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /lib/xnlogic/man
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xnlogic.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Darrick Wiebe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Xnlogic
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'xnlogic'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install xnlogic
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/xnlogic/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'xn_gem_release_tasks'
4
+ XNGemReleaseTasks.setup Xnlogic, 'lib/xnlogic/version.rb'
5
+
6
+ begin
7
+ require 'ronn'
8
+
9
+ namespace :man do
10
+ directory "lib/xnlogic/man"
11
+
12
+ Dir["man/*.ronn"].each do |ronn|
13
+ basename = File.basename(ronn, ".ronn")
14
+ roff = "lib/xnlogic/man/#{basename}"
15
+
16
+ file roff => ["lib/xnlogic/man", ronn] do
17
+ sh "#{Gem.ruby} -S ronn --roff --pipe #{ronn} > #{roff}"
18
+ end
19
+
20
+ file "#{roff}.txt" => roff do
21
+ sh "groff -Wall -mtty-char -mandoc -Tascii #{roff} | col -b > #{roff}.txt"
22
+ end
23
+
24
+ task :build_all_pages => "#{roff}.txt"
25
+ end
26
+
27
+ desc "Build the man pages"
28
+ task :build => "man:build_all_pages"
29
+
30
+ desc "Clean up from the built man pages"
31
+ task :clean do
32
+ rm_rf "lib/xnlogic/man"
33
+ end
34
+ end
35
+
36
+ rescue LoadError
37
+ namespace :man do
38
+ task(:build) { warn "Install the ronn gem to be able to release!" }
39
+ task(:clean) { warn "Install the ronn gem to be able to release!" }
40
+ end
41
+ end
42
+
43
+ task :build => ['man:clean', 'man:build']
data/bin/xnlogic ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Exit cleanly from an early interrupt
4
+ Signal.trap("INT") { exit 1 }
5
+
6
+ require 'xnlogic'
7
+
8
+ require 'xnlogic/friendly_errors'
9
+ Xnlogic.with_friendly_errors do
10
+ require 'xnlogic/cli'
11
+ Xnlogic::CLI.start(ARGV, :debug => true)
12
+ end
13
+
@@ -0,0 +1,60 @@
1
+ require 'pathname'
2
+
3
+ module Xnlogic
4
+ class CLI::Application
5
+ attr_reader :options, :app_name, :thor, :name, :target
6
+
7
+ def initialize(options, app_name, thor)
8
+ @options = options
9
+ @app_name = app_name
10
+ @thor = thor
11
+
12
+ @name = app_name.chomp("/").tr('-', '_') # remove trailing slash if present
13
+ @target = Pathname.pwd.join(name)
14
+ end
15
+
16
+ def run
17
+ namespaced_path = name
18
+ constant_name = namespaced_path.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
19
+ git_user_name = `git config user.name`.chomp
20
+ git_user_email = `git config user.email`.chomp
21
+
22
+ opts = {
23
+ :name => name,
24
+ :namespaced_path => namespaced_path,
25
+ :constant_name => constant_name,
26
+ :author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
27
+ :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
28
+ }
29
+
30
+ templates = {
31
+ "gitignore.tt" => ".gitignore",
32
+ ".rspec.tt" => ".rspec",
33
+ "Gemfile.tt" => "Gemfile",
34
+ "Readme.md.tt" => "Readme.md",
35
+ "lib/gemname.rb.tt" => "lib/#{namespaced_path}.rb",
36
+ "lib/gemname/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
37
+ "lib/gemname/initializers/inflections.rb.tt" => "lib/#{namespaced_path}/initializers/inflections.rb",
38
+ "lib/gemname/parts/has_notes.rb.tt" => "lib/#{namespaced_path}/parts/has_notes.rb",
39
+ "lib/gemname/parts/note.rb.tt" => "lib/#{namespaced_path}/parts/note.rb",
40
+ "lib/gemname/type/url.rb.tt" => "lib/#{namespaced_path}/type/url.rb",
41
+ "lib/gemname/fixtures.rb.tt" => "lib/#{namespaced_path}/fixtures.rb",
42
+ "lib/gemname/models.rb.tt" => "lib/#{namespaced_path}/models.rb",
43
+ "lib/gemname/permissions.rb.tt" => "lib/#{namespaced_path}/permissions.rb",
44
+ "lib/gemname/type.rb.tt" => "lib/#{namespaced_path}/type.rb",
45
+ "lib/fixtures/sample_fixtures.rb.tt" => "lib/fixtures/sample_fixtures.rb",
46
+
47
+ "spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
48
+ "spec/gemname/gemname_spec.rb.tt" => "spec/#{namespaced_path}/#{name}_spec.rb",
49
+ }
50
+
51
+ templates.each do |src, dst|
52
+ thor.template("application/#{src}", target.join(dst), opts)
53
+ end
54
+
55
+ Xnlogic.ui.info "Initializing git repo in #{target}"
56
+ Dir.chdir(target) { `git init`; `git add .` }
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,73 @@
1
+ require 'thor'
2
+
3
+ module Xnlogic
4
+ class CLI < Thor
5
+ include Thor::Actions
6
+
7
+ def self.start(*)
8
+ super
9
+ rescue Exception => e
10
+ Xnlogic.ui = UI::Shell.new
11
+ raise e
12
+ end
13
+
14
+ def initialize(*args)
15
+ super
16
+ rescue UnknownArgumentError => e
17
+ raise InvalidOption, e.message
18
+ ensure
19
+ self.options ||= {}
20
+ Xnlogic.ui = UI::Shell.new(options)
21
+ Xnlogic.ui.level = "debug" if options["verbose"]
22
+ end
23
+
24
+ check_unknown_options!(:except => [:config, :exec])
25
+
26
+ # Stop parsing of options as soon as an unknown option or a regular argument is encountered. All remaining arguments are passed to the task. This
27
+ # is useful if you have a task that can receive arbitrary additional options, and where those additional options should not be handled by Thor.
28
+ stop_on_unknown_option! :exec
29
+
30
+ class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
31
+
32
+ class_option "verbose", :type => :boolean, :banner => "Enable verbose output mode", :aliases => "-V"
33
+
34
+ def help(cli = nil)
35
+ case cli
36
+ when nil then command = "xnlogic"
37
+ else command = "xnlogic-#{cli}"
38
+ end
39
+
40
+ manpages = %w(
41
+ xnlogic)
42
+
43
+ if manpages.include?(command)
44
+ root = File.expand_path("../man", __FILE__)
45
+
46
+ if Xnlogic.which("man") && root !~ %r{^file:/.+!/META-INF/jruby.home/.+}
47
+ Kernel.exec "man #{root}/#{command}"
48
+ else
49
+ puts File.read("#{root}/#{command}.txt")
50
+ end
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def self.handle_no_command_error(command, has_namespace = $thor_runner)
57
+ return super unless command_path = Xnlogic.which("xnlogic-#{command}")
58
+
59
+ Kernel.exec(command_path, *ARGV[1..-1])
60
+ end
61
+
62
+ desc "application NAME [OPTIONS]", "Creates a skeleton for creating an XN Logic application"
63
+ def application(name)
64
+ require 'xnlogic/cli/application'
65
+ Application.new(options, name, self).run
66
+ end
67
+
68
+ def self.source_root
69
+ File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,50 @@
1
+ require "thor"
2
+
3
+ # Create Thor classes if they don't exist already
4
+ class Thor
5
+ class AmbiguousTaskError; end
6
+ class UndefinedTaskError; end
7
+ class Error; end
8
+ end
9
+
10
+ module Xnlogic
11
+ def self.with_friendly_errors
12
+ yield
13
+ rescue Xnlogic::XnlogicError => e
14
+ Xnlogic.ui.error e.message, :wrap => true
15
+ Xnlogic.ui.trace e
16
+ exit e.status_code
17
+ rescue Thor::AmbiguousTaskError => e
18
+ Xnlogic.ui.error e.message
19
+ exit 15
20
+ rescue Thor::UndefinedTaskError => e
21
+ Xnlogic.ui.error e.message
22
+ exit 15
23
+ rescue Thor::Error => e
24
+ Xnlogic.ui.error e.message
25
+ exit 1
26
+ rescue LoadError => e
27
+ raise e unless e.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
28
+ Xnlogic.ui.error "\nCould not load OpenSSL."
29
+ Xnlogic.ui.warn <<-WARN, :wrap => true
30
+ You must recompile Ruby with OpenSSL support or change the sources in your \
31
+ Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL \
32
+ using RVM are available at http://rvm.io/packages/openssl.
33
+ WARN
34
+ Xnlogic.ui.trace e
35
+ exit 1
36
+ rescue Interrupt => e
37
+ Xnlogic.ui.error "\nQuitting..."
38
+ Xnlogic.ui.trace e
39
+ exit 1
40
+ rescue SystemExit => e
41
+ exit e.status
42
+ rescue Exception => e
43
+ Xnlogic.ui.error <<-ERR, :wrap => true
44
+ Unfortunately, a fatal error has occurred. Please see the XN Logic \
45
+ ZenDesk support pages: https://xnlogic.zendesk.com/hc/en-us
46
+ ERR
47
+ raise e
48
+ end
49
+ end
50
+
@@ -0,0 +1,46 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "XNLOGIC" "1" "November 2014" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBxnlogic\fR \- XN Logic Command\-line Tools
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBxnlogic\fR COMMAND [\-\-no\-color] [\-\-verbose] [ARGS]
11
+ .
12
+ .SH "DESCRIPTION"
13
+ XN Logic is a graph database\-backed application framework\.
14
+ .
15
+ .P
16
+ See the XN Logic website \fIhttps://xnlogic\.com\fR for information on getting started, or https://xnlogic\.zendesk\.com/hc/en\-us for support\.
17
+ .
18
+ .SH "OPTIONS"
19
+ .
20
+ .TP
21
+ \fB\-\-no\-color\fR
22
+ Prints all output without color
23
+ .
24
+ .TP
25
+ \fB\-\-verbose\fR
26
+ Prints out additional logging information
27
+ .
28
+ .SH "COMMANDS"
29
+ We divide \fBxnlogic\fR subcommands into primary commands and utilities\.
30
+ .
31
+ .SH "PRIMARY COMMANDS"
32
+ .
33
+ .IP "\(bu" 4
34
+ \&\.\.\.
35
+ .
36
+ .IP "\(bu" 4
37
+ \fBxnlogic help(1)\fR: Displays detailed help for each subcommand
38
+ .
39
+ .IP "" 0
40
+ .
41
+ .SH "UTILITIES"
42
+ .
43
+ .TP
44
+ \fBxnlogic application(1)\fR
45
+ Create a simple application, suitable for development with xnlogic
46
+
@@ -0,0 +1,42 @@
1
+ XNLOGIC(1) XNLOGIC(1)
2
+
3
+
4
+
5
+ NAME
6
+ xnlogic - XN Logic Command-line Tools
7
+
8
+ SYNOPSIS
9
+ xnlogic COMMAND [--no-color] [--verbose] [ARGS]
10
+
11
+ DESCRIPTION
12
+ XN Logic is a graph database-backed application framework.
13
+
14
+ See the XN Logic website https://xnlogic.com for information on getting
15
+ started, or https://xnlogic.zendesk.com/hc/en-us for support.
16
+
17
+ OPTIONS
18
+ --no-color
19
+ Prints all output without color
20
+
21
+ --verbose
22
+ Prints out additional logging information
23
+
24
+ COMMANDS
25
+ We divide xnlogic subcommands into primary commands and utilities.
26
+
27
+ PRIMARY COMMANDS
28
+ o ...
29
+
30
+ o xnlogic help(1): Displays detailed help for each subcommand
31
+
32
+
33
+
34
+ UTILITIES
35
+ xnlogic application(1)
36
+ Create a simple application, suitable for development with
37
+ xnlogic
38
+
39
+
40
+
41
+
42
+ November 2014 XNLOGIC(1)
@@ -0,0 +1,2 @@
1
+ -f d
2
+ -p
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'pacer'
4
+ gem 'pacer-neo4j'
5
+ gem 'pacer-model'
6
+ gem 'pacer-mcfly'
@@ -0,0 +1,86 @@
1
+ # <%= config[:name] %>
2
+
3
+ This gem provides the domain model and business logic for ...
4
+
5
+ # Getting a New Environment Set Up
6
+
7
+ TODO: Add vagrant setup instructions.
8
+
9
+ # Starting up the Development Console
10
+
11
+ To use this model, simply require the gem and work the graph like you're used to with pacer.
12
+
13
+ To start an IRB console session in the terminal, log into the VM and:
14
+
15
+ ```
16
+ xn console <%= config[:name] %>
17
+ ```
18
+
19
+ The first time you use the application, you must instantiate a client application. To do that from the console:
20
+
21
+ ```ruby
22
+ PM.create_client '<%= config[:name] %>', 'client_app_name'
23
+ ```
24
+
25
+ You can create as many clients for your application as you like. Once you create a client, it will still be available across restarts of the
26
+ application. To get a reference to your client application and the graph that it points to, run:
27
+
28
+ ```ruby
29
+ app = PM['client_app_name']
30
+ graph = app.graph
31
+ ```
32
+
33
+ And that's it! Now just rock your XN skills and Pacer-foo on top of your application model ;)
34
+
35
+ ## Testing the REST API within the Dev Console
36
+
37
+ Start by getting a reference to the application instance (see above). Once you have that, you'll need to get XN to generate the
38
+ console REST endpoints with this command:
39
+
40
+ ```ruby
41
+ include app.console
42
+ ```
43
+
44
+ Now you can execute commands with `xget`, `xpost`, `xpatch`, `xdelete`, `xput`, as follows:
45
+
46
+ ```ruby
47
+ xget '/model/some_model/id/123'
48
+
49
+ # NOTE that hash keys in requests must be strings:
50
+
51
+ xput '/model/some_model', {'name' => 'Record Name'}
52
+ ```
53
+
54
+
55
+ # Fixtures
56
+
57
+ You can create fixture data for your app or for a sample app by creating fixture files in
58
+ `lib/fixtures`. Run `xn sample_fixtures` to see a sample fixtures file.
59
+
60
+ Load:
61
+
62
+ ```ruby
63
+ require 'gemname/fixtures.rb'
64
+ GemName::Fixtures.load_fixtures app
65
+ ```
66
+
67
+ # Export to GraphML
68
+
69
+ (yFiles)[http://www.yworks.com/en/products_yed_about.html] (yfiles will not recognize the file with an incorrect extension):
70
+
71
+ ```ruby
72
+ require 'pacer/utils/y_files'
73
+ exp = Pacer::Util::YFiles.new
74
+ exp.export graph, "/tmp/example.graphml"
75
+ ```
76
+
77
+
78
+ Also, you can load and GraphML back into the graph with:
79
+
80
+ ```ruby
81
+ Pacer::GraphML.import graph, "/tmp/example.graphml"
82
+ ```
83
+
84
+ # Copyright
85
+ Copyright XN Logic Corporation, 2014. All rights reserved.
86
+ Contact us@xnlogic.com for usage restrictions.
@@ -0,0 +1,9 @@
1
+ *.sw?
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ Jarfile.lock
6
+ Jarfile.*.lock
7
+ pkg/*
8
+ bin/*
9
+ tmp/
@@ -0,0 +1,53 @@
1
+ module <%= config[:constant_name] %>
2
+ module Fixtures
3
+
4
+ # TODO: create your own fixtures!
5
+ class UsersFixture < Fixture
6
+ # We define that the UsersFixture depends on the GroupsFixture
7
+ def self.depends_on
8
+ [:GroupsFixture]
9
+ end
10
+
11
+ # This method is optional. Use it to clean up fixture data.
12
+ #
13
+ # NB: This is called each time before load is called.
14
+ def delete
15
+ app.find(<%= config[:constant_name] %>::M::UserAccount, 'david').delete!
16
+ app.find(<%= config[:constant_name] %>::M::UserAccount, 'darrick').delete!
17
+ end
18
+
19
+ def load
20
+ # This fixture method just calls the helper defined below
21
+ create_user 'david', 'David Colebatch', 'dc@xnlogic.com', ['support']
22
+ create_user 'darrick', 'Darrick Wiebe', 'dw@xnlogic.com', ['support']
23
+ end
24
+
25
+ private # HELPERS
26
+
27
+ # This is just a helper method to demonstrate that fixtures are just regular Ruby code.
28
+ def create_user(id, name, email, groups)
29
+ groups = groups.map { |g| app.find(<%= config[:constant_name] %>::M::Group, g) }
30
+ app.create(<%= config[:constant_name] %>::M::UserAccount, id, name: name, email: email) do |user|
31
+ groups.each do |group|
32
+ user.inherit_full_access group
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ class GroupsFixture < Fixture
40
+ # This method is optional. Use it to clean up fixture data.
41
+ #
42
+ # NB: This is called each time before load is called.
43
+ def delete
44
+ app.find(<%= config[:constant_name] %>::M::Group, 'support').delete!
45
+ end
46
+
47
+ def load
48
+ # We specify the Group model, an ID and then a list of property values:
49
+ app.create(<%= config[:constant_name] %>::M::Group, 'support', name: 'XN Logic Support')
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,108 @@
1
+ require 'tsort'
2
+
3
+ module <%= config[:constant_name] %>
4
+ module Fixtures
5
+ class Fixture
6
+ class << self
7
+ include TSort
8
+
9
+ def inherited(klass)
10
+ @inherited ||= []
11
+ @inherited = (@inherited + [klass]).sort_by &:name
12
+ end
13
+
14
+ def tsort_each_child(node, &block)
15
+ if node.respond_to? :depends_on
16
+ children = node.depends_on.flat_map do |n|
17
+ @inherited.select do |f|
18
+ f.name.split(/::/).last.to_sym == n
19
+ end
20
+ end
21
+ children.each &block
22
+ end
23
+ end
24
+
25
+ def tsort_each_node(&block)
26
+ @inherited.each &block if @inherited
27
+ end
28
+ end
29
+
30
+ attr_reader :app
31
+
32
+ def initialize(app, commit, rollback)
33
+ @app = app
34
+ @commit = commit
35
+ @rollback = rollback
36
+ end
37
+
38
+ def load
39
+ throw "Fixture #{ self.class.name } does nothing. Define a load method."
40
+ end
41
+
42
+ def delete
43
+ end
44
+
45
+ def commit
46
+ @commit.call
47
+ end
48
+
49
+ def rollback
50
+ @rollback.call
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ module <%= config[:constant_name] %>
57
+ module Fixtures
58
+ class << self
59
+ def load_fixtures(app)
60
+ delete_fixtures(app)
61
+ start_time = Time.now
62
+ app.graph.transaction do |commit, rollback|
63
+ <%= config[:constant_name] %>::Fixtures::Fixture.tsort.each do |fixture|
64
+ puts "Loading fixture: #{ fixture }"
65
+ f = fixture.new(app, commit, rollback)
66
+ f.load
67
+ end
68
+ end
69
+ puts "Loaded fixtures in #{ Time.now - start_time } seconds (#{app.graph.v.count} vertices, #{app.graph.e.count} edges)"
70
+ end
71
+
72
+ def delete_fixtures(app)
73
+ if app.graph.v.count > 300
74
+ raise "Error deleting fixture data. Node count > 300, possible production data."
75
+ end
76
+ reload_fixture_files
77
+ start_time = Time.now
78
+ app.create_indices!(app.graph)
79
+ app.graph.transaction do |commit, rollback|
80
+ <%= config[:constant_name] %>::Fixtures::Fixture.tsort.each do |fixture|
81
+ puts "Deleting fixture data: #{ fixture }"
82
+ fixture.new(app, commit, rollback).delete
83
+ end
84
+ end
85
+ app.generate_metadata!
86
+ puts "Deleted fixtures in #{ Time.now - start_time } seconds (#{app.graph.v.count} vertices, #{app.graph.e.count} edges)"
87
+ end
88
+
89
+ private
90
+
91
+ def fixtures_dir
92
+ <%= config[:constant_name] %>.lib_dir + 'fixtures'
93
+ end
94
+
95
+ def reload_fixture_files
96
+ if Dir[fixtures_dir + '*.rb'].any?
97
+ puts "Loading .rb fixtures from #{fixtures_dir}:"
98
+ Dir[fixtures_dir + '*.rb'].each do |path|
99
+ puts "Loading ruby file: #{path}"
100
+ load path
101
+ end
102
+ else
103
+ puts "Can't reload fixtures without the source code"
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end