graphql-analyzer 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 54473f98c98849d98f903aecb9b5d7cc8884814f
4
+ data.tar.gz: bd20e305c491fbe3e2995e1557e235b0c2d629c5
5
+ SHA512:
6
+ metadata.gz: dbfd0003f66c9af1f6a39b77508acd9b837c3232318245733c9c29fc93bcb6d7237a267762a642d04c413277f1659bab678d916259438836f615b362b1592141
7
+ data.tar.gz: 2cffb2f07dd330c17b543acedc9c114ab4722f7fa951e3f21260f3bd43335a0218e230a670c0f697e12951e5ccd638fb2c73a68df65ac8700e62867b04ed064d
@@ -0,0 +1,37 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ ## Specific to RubyMotion:
14
+ .dat*
15
+ .repl_history
16
+ build/
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ Gemfile.lock
32
+ .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
37
+ *.sqlite3
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.4.1
5
+
6
+ cache: bundler
7
+
8
+ services:
9
+ - mysql
10
+ - postgresql
11
+
12
+ before_install:
13
+ - mysql -e 'CREATE DATABASE graphql_analyzer_test;'
14
+ - psql -c 'CREATE DATABASE graphql_analyzer_test;' -U postgres
15
+
16
+ notifications:
17
+ email:
18
+ on_success: never
19
+ on_failure: always
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in graphql-analyzer.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 DerekStride
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,136 @@
1
+ # GraphQL::Analyzer
2
+
3
+ [![Build Status](https://travis-ci.org/GraphQL-Query-Planner/graphql-analyzer.svg?branch=master)](https://travis-ci.org/GraphQL-Query-Planner/graphql-analyzer)
4
+
5
+ GraphQL Analyzer is a [GraphQL](https://github.com/rmosolgo/graphql-ruby) extension for tracking datastore queries.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'graphql-analyzer'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install graphql-analyzer
22
+
23
+ ## Usage
24
+
25
+ Add an instance of GraphQL::Analyzer to your schema, instantiate it with a list of instrumentations to capture different datastore queries.
26
+
27
+ ### Analyzer
28
+
29
+ Add 'GraphQL::Analyzer' to your schema:
30
+
31
+ ```ruby
32
+ require 'graphql/analyzer'
33
+
34
+ Schema = GraphQL::Schema.define do
35
+ query QueryType
36
+ use(
37
+ GraphQL::Analyzer.new(
38
+ GraphQL::Analyzer::Instrumentation::Mysql.new,
39
+ GraphQL::Analyzer::Instrumentation::Postgresql.new
40
+ )
41
+ )
42
+ end
43
+ ```
44
+
45
+ ### Response Format
46
+
47
+ The GraphQL specification allows servers to [include additional information as part of the response under an `extensions` key](https://facebook.github.io/graphql/#sec-Response-Format):
48
+
49
+ > The response map may also contain an entry with key `extensions`. This entry, if set, must have a map as its value. This entry is reserved for implementors to extend the protocol however they see fit, and hence there are no additional restrictions on its contents.
50
+
51
+ GraphQL Analyzer exposes datastore query data for an individual request under a `analyzer` key in `extensions`:
52
+
53
+ ```json
54
+ {
55
+ "data": <>,
56
+ "errors": <>,
57
+ "extensions": {
58
+ "analyzer": {
59
+ "version": 1,
60
+ "execution": {
61
+ "resolvers": [
62
+ {
63
+ "path": [
64
+ "node"
65
+ ],
66
+ "adapter": "sqlite3",
67
+ "parentType": "Query",
68
+ "fieldName": "node",
69
+ "returnType": "Node",
70
+ "details": {
71
+ "root": "EXPLAIN for: SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = ? LIMIT ? [[\"id\", 7], [\"LIMIT\", 1]",
72
+ "explained_queries": [
73
+ {
74
+ "select_id": "0",
75
+ "order": "0",
76
+ "from": "0",
77
+ "details": "SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?)"
78
+ }
79
+ ]
80
+ }
81
+ }
82
+ ]
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### Instrumentation
90
+
91
+ There are some common instruments already implemented that should work right away.
92
+
93
+ - `Sqlite3`
94
+ - `Mysql`
95
+ - `Postgresql`
96
+
97
+ Check [`lib/graphql/analyzer/instrumentation`](https://github.com/GraphQL-Query-Planner/graphql-analyzer/tree/master/lib/graphql/analyzer/instrumentation) for the full list.
98
+
99
+ To write your own custom instrumentation, your object needs to respond to `#instrument(type, field)` and return a lambda that accepts three parameters, `object`, `arguments`, and `context`, and returns the original field value. It should also add any queries captured to the `context`.
100
+
101
+ ```ruby
102
+ module GraphQL
103
+ class Analyzer
104
+ module Instrumentation
105
+ class MyCustomInstrumentation < Base
106
+ def instrument(type, field)
107
+ ->(obj, args, ctx) do
108
+ ### OMITTED ###
109
+ ctx['graphql-analyzer']['resolvers'] << {
110
+ 'adapter' => 'My Custom Adapter',
111
+ 'path' => ctx.path,
112
+ 'parentType' => type.name,
113
+ 'fieldName' => field.name,
114
+ 'returnType' => field.type.to_s,
115
+ 'details' => 'My Adapter Specific Information'
116
+ }
117
+ ### OMITTED ###
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ ```
125
+
126
+ ## Development
127
+
128
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
129
+
130
+ ## Contributing
131
+
132
+ Bug reports and pull requests are welcome on GitHub at https://github.com/GraphQL-Query-Planner/graphql-analyzer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
133
+
134
+ ## License
135
+
136
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'pry-byebug'
4
+ Dir.glob('tasks/*.rake').each { |task_file| load task_file}
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
@@ -0,0 +1,36 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "graphql/analyzer/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "graphql-analyzer"
8
+ spec.version = GraphQL::Analyzer::VERSION
9
+ spec.authors = ["DerekStride"]
10
+ spec.email = ["djgstride@gmail.com"]
11
+
12
+ spec.summary = %q{An analysis tool for graphql-ruby schemas.}
13
+ spec.description = %q{An analysis tool for graphql-ruby schemas.}
14
+ spec.homepage = "https://github.com/GraphQL-Query-Planner/graphql-analyzer"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency "graphql", ">= 0.8", "< 2"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.16"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "factory_bot"
30
+ spec.add_development_dependency "pry-byebug"
31
+ spec.add_development_dependency "activerecord"
32
+ spec.add_development_dependency "mysql2"
33
+ spec.add_development_dependency "sqlite3"
34
+ spec.add_development_dependency "pg", "~> 0.18"
35
+ spec.add_development_dependency "globalid"
36
+ end
@@ -0,0 +1,51 @@
1
+ require "graphql"
2
+ require "graphql/analyzer/version"
3
+ require "graphql/analyzer/instrumentation/base"
4
+ require "graphql/analyzer/instrumentation/mysql"
5
+ require "graphql/analyzer/instrumentation/postgresql"
6
+ require "graphql/analyzer/instrumentation/sqlite3"
7
+ require "graphql/analyzer/parser/base"
8
+ require "graphql/analyzer/parser/mysql"
9
+ require "graphql/analyzer/parser/postgresql"
10
+ require "graphql/analyzer/parser/sqlite3"
11
+ require "graphql/analyzer/result"
12
+
13
+ module GraphQL
14
+ class Analyzer
15
+ attr_reader :instruments
16
+ private :instruments
17
+
18
+ def initialize(instruments)
19
+ @instruments = instruments
20
+ end
21
+
22
+ def use(schema_definition)
23
+ schema_definition.instrument(:query, self)
24
+ schema_definition.instrument(:field, self)
25
+ end
26
+
27
+ def before_query(query)
28
+ query.context['graphql-analyzer'] = { 'resolvers' => [] }
29
+ end
30
+
31
+ def after_query(query)
32
+ result = query.result
33
+
34
+ result["extensions"] ||= {}
35
+ result["extensions"]["analyzer"] = {
36
+ "version" => 1,
37
+ "execution" => {
38
+ "resolvers" => query.context['graphql-analyzer']['resolvers']
39
+ }
40
+ }
41
+ end
42
+
43
+ def instrument(type, field)
44
+ instruments.reduce(field) do |field, instrumentation|
45
+ field.redefine { resolve(instrumentation.instrument(type, field)) }
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+
@@ -0,0 +1,43 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Instrumentation
4
+ class Base
5
+ def instrument(type, field)
6
+ ->(obj, args, ctx) do
7
+ result = nil
8
+ queries = ::ActiveRecord::Base.collecting_queries_for_explain do
9
+ result = field.resolve_proc.call(obj, args, ctx)
10
+ result.to_a if result.respond_to?(:to_a)
11
+ end
12
+
13
+ if queries.any?
14
+ explain_output = ::ActiveRecord::Base.exec_explain(queries)
15
+ parsed_output = parser.parse(explain_output)
16
+
17
+ # TODO: Merge results when a field makes two types of queries
18
+ # e.g. path: ['user', 'name'] makes a SQL and ES Query.
19
+ ctx['graphql-analyzer']['resolvers'] << {
20
+ 'path' => ctx.path,
21
+ 'adapter' => adapter,
22
+ 'parentType' => type.name,
23
+ 'fieldName' => field.name,
24
+ 'returnType' => field.type.to_s,
25
+ 'details' => parsed_output
26
+ }
27
+ end
28
+
29
+ result
30
+ end
31
+ end
32
+ end
33
+
34
+ def parser
35
+ raise NotImplementedError, "Please override in #{self.class.name}"
36
+ end
37
+
38
+ def adapter
39
+ raise NotImplementedError, "Please override in #{self.class.name}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Instrumentation
4
+ class Mysql < Base
5
+ private
6
+
7
+ def parser
8
+ Parser::Mysql
9
+ end
10
+
11
+ def adapter
12
+ @adapter ||= 'mysql'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Instrumentation
4
+ class Postgresql < Base
5
+ private
6
+
7
+ def parser
8
+ Parser::Postgresql
9
+ end
10
+
11
+ def adapter
12
+ @adapter ||= 'postgresql'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Instrumentation
4
+ class Sqlite3 < Base
5
+ private
6
+
7
+ def parser
8
+ Parser::Sqlite3
9
+ end
10
+
11
+ def adapter
12
+ @adapter ||= 'sqlite3'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Parser
4
+ class Base
5
+ class << self
6
+ def parse(explain_output)
7
+ new(explain_output).result
8
+ end
9
+ end
10
+
11
+ attr_reader :explain_output
12
+
13
+ def initialize(explain_output)
14
+ @explain_output = explain_output
15
+ end
16
+
17
+ def result
18
+ @result ||= parse
19
+ end
20
+
21
+ private
22
+
23
+ def parse
24
+ raise NotImplementedError, "Please override in #{self.class.name}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Parser
4
+ class Mysql < Base
5
+ private
6
+
7
+ def parse
8
+ root, keys, *values, _ = explain_output.split("\n").reject { |line| line =~ /^\+.*\+$/ }
9
+ fields = keys[1..-1].split('|').map(&:strip).map(&:downcase)
10
+
11
+ explained_queries = values.map do |value|
12
+ parsed_value = value[1..-1].split("|").map(&:strip)
13
+ fields.zip(parsed_value).to_h
14
+ end
15
+
16
+ Result.new(root, explained_queries)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Parser
4
+ class Postgresql < Base
5
+ private
6
+
7
+ def parse
8
+ root, *values, _ = explain_output.split("\n").reject { |line| line =~ /(QUERY\ PLAN)|-{5,}/ }
9
+ Result.new(root, [values.join("\n")])
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ module Parser
4
+ class Sqlite3 < Base
5
+ FIELDS = %w(select_id order from details).freeze
6
+
7
+ private
8
+
9
+ def parse
10
+ root, *values = explain_output.split("\n")
11
+ explained_queries = values.map { |value| FIELDS.zip(value.split("|").map(&:strip)).to_h }
12
+ Result.new(root, explained_queries)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ class Result
4
+ attr_accessor :path
5
+ attr_reader :root, :explained_queries
6
+ alias_method :queries, :explained_queries
7
+
8
+ def initialize(root, explained_queries)
9
+ @root = root
10
+ @explained_queries = explained_queries
11
+ end
12
+
13
+ def to_h
14
+ {
15
+ query: root,
16
+ details: explained_queries,
17
+ path: path
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module GraphQL
2
+ class Analyzer
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,77 @@
1
+ require 'yaml'
2
+ require 'logger'
3
+ require 'active_record'
4
+
5
+ namespace :db do
6
+ def create_database(config)
7
+ options = { charset: 'utf8', collation: 'utf8_unicode_ci' }
8
+
9
+ create_db = lambda do |config|
10
+ ActiveRecord::Base.establish_connection(config.merge('database' => nil))
11
+ ActiveRecord::Base.connection.create_database(config['database'], options)
12
+ ActiveRecord::Base.establish_connection(config)
13
+ end
14
+
15
+ begin
16
+ create_db.call(config)
17
+ rescue Mysql::Error => sqlerr
18
+ if sqlerr.errno == 1405
19
+ print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
20
+ root_password = $stdin.gets.strip
21
+
22
+ grant_statement = <<-SQL
23
+ GRANT ALL PRIVILEGES ON #{config['database']}.*
24
+ TO '#{config['username']}'@'localhost'
25
+ IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;
26
+ SQL
27
+
28
+ create_db.call config.merge('database' => nil, 'username' => 'root', 'password' => root_password)
29
+ else
30
+ $stderr.puts sqlerr.error
31
+ $stderr.puts "Couldn't create database for #{config.inspect}, charset: utf8, collation: utf8_unicode_ci"
32
+ $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
33
+ end
34
+ end
35
+ end
36
+
37
+ task :environment do
38
+ DATABASE_ENV = ENV['DATABASE_ENV'] || 'test'
39
+ MIGRATIONS_DIR = ENV['MIGRATIONS_DIR'] || 'spec/support/active_record/db/migrate'
40
+ end
41
+
42
+ task :configuration => :environment do
43
+ @config = YAML.load_file('spec/support/active_record/config/databases.yml')[DATABASE_ENV]
44
+ end
45
+
46
+ task :configure_connection => :configuration do
47
+ ActiveRecord::Base.establish_connection @config
48
+ ActiveRecord::Base.logger = Logger.new STDOUT if @config['logger']
49
+ end
50
+
51
+ desc 'Create the database from config/database.yml for the current DATABASE_ENV'
52
+ task :create => :configure_connection do
53
+ create_database @config
54
+ end
55
+
56
+ desc 'Drops the database for the current DATABASE_ENV'
57
+ task :drop => :configure_connection do
58
+ ActiveRecord::Base.connection.drop_database @config['database']
59
+ end
60
+
61
+ desc 'Migrate the database (options: VERSION=x, VERBOSE=false).'
62
+ task :migrate => :configure_connection do
63
+ ActiveRecord::Migration.verbose = true
64
+ ActiveRecord::Migrator.migrate MIGRATIONS_DIR, ENV['VERSION'] ? ENV['VERSION'].to_i : nil
65
+ end
66
+
67
+ desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
68
+ task :rollback => :configure_connection do
69
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
70
+ ActiveRecord::Migrator.rollback MIGRATIONS_DIR, step
71
+ end
72
+
73
+ desc "Retrieves the current schema version number"
74
+ task :version => :configure_connection do
75
+ puts "Current version: #{ActiveRecord::Migrator.current_version}"
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-analyzer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - DerekStride
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: graphql
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0.8'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.16'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.16'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: factory_bot
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: pry-byebug
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: activerecord
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: mysql2
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: sqlite3
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: pg
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.18'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.18'
159
+ - !ruby/object:Gem::Dependency
160
+ name: globalid
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ description: An analysis tool for graphql-ruby schemas.
174
+ email:
175
+ - djgstride@gmail.com
176
+ executables: []
177
+ extensions: []
178
+ extra_rdoc_files: []
179
+ files:
180
+ - ".gitignore"
181
+ - ".travis.yml"
182
+ - Gemfile
183
+ - LICENSE.txt
184
+ - README.md
185
+ - Rakefile
186
+ - graphql-analyzer.gemspec
187
+ - lib/graphql/analyzer.rb
188
+ - lib/graphql/analyzer/instrumentation/base.rb
189
+ - lib/graphql/analyzer/instrumentation/mysql.rb
190
+ - lib/graphql/analyzer/instrumentation/postgresql.rb
191
+ - lib/graphql/analyzer/instrumentation/sqlite3.rb
192
+ - lib/graphql/analyzer/parser/base.rb
193
+ - lib/graphql/analyzer/parser/mysql.rb
194
+ - lib/graphql/analyzer/parser/postgresql.rb
195
+ - lib/graphql/analyzer/parser/sqlite3.rb
196
+ - lib/graphql/analyzer/result.rb
197
+ - lib/graphql/analyzer/version.rb
198
+ - tasks/database.rake
199
+ homepage: https://github.com/GraphQL-Query-Planner/graphql-analyzer
200
+ licenses:
201
+ - MIT
202
+ metadata: {}
203
+ post_install_message:
204
+ rdoc_options: []
205
+ require_paths:
206
+ - lib
207
+ required_ruby_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ required_rubygems_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ requirements: []
218
+ rubyforge_project:
219
+ rubygems_version: 2.6.11
220
+ signing_key:
221
+ specification_version: 4
222
+ summary: An analysis tool for graphql-ruby schemas.
223
+ test_files: []