active_recorder 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5abf615aff84554c27a041a67348ba25be5aa1b8
4
+ data.tar.gz: 0d1c4284804446e71b691cb395ad6e7308ecf924
5
+ SHA512:
6
+ metadata.gz: c1f35777e8b4fc1ce7040f0e7c94bf240a810ffb75cb179ca1093e8719b75a3c87a5d05b1751bab2aa30550b3be96cd36fb71d6a39b0358a05978c724a3e174f
7
+ data.tar.gz: 56cb13a0bbcab62027be5bb3907c2b79a712f42ba4c4f17fcded4397fe78d07b8ba3c8a445aef7282418bba7c65468f6b549e7c6ab0192debf25eeb4bdd844c7
@@ -0,0 +1,18 @@
1
+ require 'active_recorder/filereader'
2
+ require 'active_recorder/filewriter'
3
+ require 'active_recorder/record'
4
+ # Main class for ActiveRecorder gem
5
+ class ActiveRecorder
6
+ def self.record(path)
7
+ # Add a tables route to routes.rb
8
+ Filewriter.write_routes(path)
9
+ # Get all the records from the
10
+ records = Filereader.construct_records(path)
11
+ # Construct tables_controller.rb
12
+ Filewriter.write_controller(path, records)
13
+ # Create a tables directory
14
+ Filewriter.create_tables_dir(path)
15
+ # Create a index file for tables
16
+ Filewriter.write_view(path, records)
17
+ end
18
+ end
@@ -0,0 +1,109 @@
1
+ # A Filereader module which creates Records based on migration files
2
+ module Filereader
3
+ # Takes in directory with migrations and returns array of records created
4
+ def self.construct_records(path)
5
+ # Initialize array of records
6
+ records = []
7
+ # Iterates through every file in a directory
8
+ dir = File.join(path, 'db/migrate')
9
+ Dir.foreach(dir) do |file|
10
+ next if file.start_with?('.')
11
+ # Append to records
12
+ records << Filereader.construct_record(Filereader.to_absolute_path(dir, file))
13
+ end
14
+ records
15
+ end
16
+
17
+ # Takes in a filename as input and constructs a Record
18
+ def self.construct_record(filename)
19
+ # Get migration file information
20
+ record_info = Filereader.get_initial_line(filename)
21
+ # Check if file was a valid migration file
22
+ fail ArgumentError, 'Not a migration file' if record_info.empty?
23
+ columns_info = Filereader.get_columns(filename, record_info['var_name'])
24
+ # Create a new record
25
+ record = Record.new(record_info['record_name'])
26
+ # Add hashed to record
27
+ columns_info.each { |column, type| record.add_column(column, type) }
28
+ record
29
+ end
30
+
31
+ # Takes in a filename and gets the column lines of the file
32
+ def self.get_columns(filename, var_name)
33
+ # Initialize a column array
34
+ columns = {}
35
+ # Opens file and retrieve column lines
36
+ File.open(filename).each do |line|
37
+ # Strip line
38
+ strs = line.strip!.split
39
+ # Adds column lines hash
40
+ if line.start_with?(var_name)
41
+ strs[1] = strs[1].slice(0, strs[1].length - 1) if strs[1].end_with?(',')
42
+ type = Filereader.to_data_type(strs[0], var_name)
43
+ columns[Filereader.to_column_name(strs[1])] = type if type != 'timestamps'
44
+ end
45
+ # Check if reach end
46
+ break if line.strip! == 'end'
47
+ end
48
+ columns
49
+ end
50
+
51
+ # Takes in a filename and gets the initial line information
52
+ def self.get_initial_line(filename)
53
+ # Initialize a hash
54
+ hash = {}
55
+ # Opens file and retrieve initial line
56
+ File.open(filename).each do |line|
57
+ # Strip line
58
+ strs = line.strip!.split
59
+ # Adds initial line
60
+ next unless !strs[0].nil? && strs[0].start_with?('create_table')
61
+ # Check if we reached end
62
+ hash['record_name'] = Filereader.to_record_name(strs[1])
63
+ hash['var_name'] = Filereader.to_variable_name(strs[3])
64
+ break
65
+ end
66
+ hash
67
+ end
68
+
69
+ # Convert to variable name
70
+ def self.to_variable_name(var)
71
+ var[1, var.length - 2]
72
+ end
73
+
74
+ # Convert table name to Entity name
75
+ def self.to_record_name(name)
76
+ entity_name = name[1, name.length - 2].capitalize
77
+ # Check if name has '_'
78
+ if name.include? '_'
79
+ entity_name = Filereader.to_association_record_name(name)
80
+ elsif name.end_with?('ses')
81
+ entity_name = name[1, name.length - 3].capitalize
82
+ end
83
+ entity_name
84
+ end
85
+
86
+ # Get association table name
87
+ def self.to_association_record_name(name)
88
+ split = name.split('_')
89
+ name = "#{split[0].slice(1, split[0].length).capitalize}#{split[1].capitalize}"
90
+ entity_name = name[0, name.length - 1]
91
+ entity_name = name[0, name.length - 2] if name.end_with?('ses')
92
+ entity_name
93
+ end
94
+
95
+ # Convert to column name
96
+ def self.to_data_type(col, var_name)
97
+ col[var_name.length + 1, col.length - var_name.length]
98
+ end
99
+
100
+ # Convert to data type
101
+ def self.to_column_name(type)
102
+ type[1, type.length - 1]
103
+ end
104
+
105
+ # Convert to absolute path
106
+ def self.to_absolute_path(dir, file)
107
+ "#{dir}/#{file}"
108
+ end
109
+ end
@@ -0,0 +1,120 @@
1
+ require 'fileutils'
2
+ # A Filereader module which create a controller and view for ActiveRecord tables
3
+ module Filewriter
4
+ # Creates controller in the directory given
5
+ def self.write_controller(path, records)
6
+ # Get the absolute path to write the controller
7
+ dir = File.join(path, 'app/controllers/tables_controller.rb')
8
+ open(dir, 'w') do |f|
9
+ # Prints class declaration
10
+ f.puts 'class TablesController < ApplicationController'
11
+ # Prints comment
12
+ f.puts ' # GET /tables'
13
+ # Prints route function
14
+ f.puts ' def index'
15
+ # Prints out entities instance variable and function call
16
+ records.each do |record|
17
+ f.puts " #{Filewriter.to_instance_variable(record.name)} = #{Filewriter.to_all(record.name)}"
18
+ end
19
+ f.puts ' end'
20
+ f.puts 'end'
21
+ end
22
+ end
23
+
24
+ # Creates a tables view in the directory given
25
+ def self.write_view(path, records)
26
+ # Get the absolute path to write the view
27
+ dir = File.join(path, 'app/views/tables/index.html.erb')
28
+ open(dir, 'w') do |f|
29
+ # Print headers
30
+ f.puts '<!DOCTYPE HTML>'
31
+ f.puts '<html lang="en">'
32
+ f.puts ' <head>'
33
+ f.puts ' <title>ActiveRecord Tables</title>'
34
+ f.puts ' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">'
35
+ f.puts ' </head>'
36
+ f.puts ' <body>'
37
+ f.puts ' <h1 align="center">ActiveRecord Tables</h1>'
38
+ # Print record tables
39
+ records.each do |record|
40
+ f.puts ' <div class="container col-md-offset-2 col-md-8">'
41
+ f.puts " <h3 align='center' style='margin-top:30px'>#{Filewriter.pluralize(record.name)} Table</h3>"
42
+ f.puts ' <table class="table table-bordered">'
43
+ f.puts ' <thead>'
44
+ f.puts ' <tr class="info">'
45
+ f.puts ' <th>ID</th>'
46
+ record.columns.each do |col, _val|
47
+ f.puts " <th>#{col.capitalize}</th>"
48
+ end
49
+ f.puts ' </tr>'
50
+ f.puts ' </thead>'
51
+ f.puts ' <tbody>'
52
+ f.puts " <% #{Filewriter.to_instance_variable(record.name)}.each do |#{record.name.downcase}| %>"
53
+ f.puts ' <tr>'
54
+ f.puts " <td><%= #{record.name.downcase}.id %></td>"
55
+ record.columns.each do |col, val|
56
+ if val == 'references'
57
+ f.puts " <td><%= #{record.name.downcase}.#{col}.id %></td>"
58
+ else
59
+ f.puts " <td><%= #{record.name.downcase}.#{col} %></td>"
60
+ end
61
+ end
62
+ f.puts ' </tr>'
63
+ f.puts ' <% end %>'
64
+ f.puts ' </tbody>'
65
+ f.puts ' </table>'
66
+ f.puts ' </div>'
67
+ end
68
+ f.puts ' </body>'
69
+ f.puts '</html>'
70
+ end
71
+ end
72
+
73
+ # Writes the tables routes to the routes.rb file
74
+ def self.write_routes(path)
75
+ # Get input and output directory of files
76
+ input = "#{File.join(path, 'config')}/routes.rb"
77
+ output = "#{File.join(path, 'config')}/tmp.rb"
78
+ # Open the file to read from
79
+ open(input, 'r') do |input_file|
80
+ open(output, 'w') do |output_file|
81
+ # Read each line of input
82
+ input_file.each_line do |line|
83
+ if line.start_with? 'end'
84
+ output_file.puts(" get 'tables' => 'tables#index'")
85
+ output_file.puts('end')
86
+ else
87
+ output_file.write(line)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ # Overwrite input with output
93
+ FileUtils.mv(output, input)
94
+ end
95
+
96
+ # Prepends '@' and appends 's' to a lower case variable name
97
+ def self.to_instance_variable(name)
98
+ instance_name = "@#{name.downcase}s"
99
+ instance_name = "@#{name.downcase}es" if name.end_with?('s')
100
+ instance_name
101
+ end
102
+
103
+ # Appends '.all' to a records name
104
+ def self.to_all(name)
105
+ "#{name}.all"
106
+ end
107
+
108
+ # Appends 's' to a records name
109
+ def self.pluralize(name)
110
+ pluralized = "#{name}s"
111
+ pluralized = "#{name}es" if name.end_with?('s')
112
+ pluralized
113
+ end
114
+
115
+ # Creates a directory with the given path
116
+ def self.create_tables_dir(path)
117
+ dir = File.join(path, 'app/views/tables')
118
+ Dir.mkdir dir
119
+ end
120
+ end
@@ -0,0 +1,29 @@
1
+ # An record class to represent an ActiveRecord table
2
+ class Record
3
+ # Instance variable: name of the Model using table
4
+ attr_reader :name
5
+ attr_accessor :columns
6
+ # Array with valid ActiveRecord datatypes
7
+ VALID_TYPES = %w(
8
+ binary boolean date datetime decimal float integer
9
+ primary_key references string text time timestamp
10
+ ).freeze
11
+
12
+ # Record constructor to initialize Record with name
13
+ def initialize(name)
14
+ # Validate name
15
+ fail ArgumentError, 'Name cannot be nil!' if name.nil?
16
+ fail ArgumentError, 'Name cannot be empty!' if name.empty?
17
+ # Initialize name and columns
18
+ @name = name
19
+ @columns = {}
20
+ end
21
+
22
+ # Adds a column to record
23
+ def add_column(col, type)
24
+ # Check whether the column added is a valid ActiveRecord type
25
+ fail ArgumentError, 'Invalid ActiveRecord datatype!' unless VALID_TYPES.include?(type)
26
+ # Add column to record
27
+ @columns[col] = type
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_recorder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Goh Chin Loong
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: The gem creates a view, controller and routes to allow Rails developers
56
+ to see their ActiveRecord tables.
57
+ email:
58
+ - gohchinloong@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - lib/active_recorder.rb
64
+ - lib/active_recorder/filewriter.rb
65
+ - lib/active_recorder/filereader.rb
66
+ - lib/active_recorder/record.rb
67
+ homepage: http://www.github.com/chinloong93
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.0.14
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: A Ruby gem which visualizes ActiveRecord tables and rows for Rails apps.
91
+ test_files: []