go-on-rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +64 -0
- data/lib/generators/gor/USAGE +30 -0
- data/lib/generators/gor/go_on_rails/association.rb +41 -0
- data/lib/generators/gor/go_on_rails/converter.rb +97 -0
- data/lib/generators/gor/gor_generator.rb +93 -0
- data/lib/generators/gor/templates/db.go.erb +26 -0
- data/lib/generators/gor/templates/favicon.ico +0 -0
- data/lib/generators/gor/templates/gor_model.go.erb +451 -0
- data/lib/generators/gor/templates/home_controller.go +27 -0
- data/lib/generators/gor/templates/index.tmpl +8 -0
- data/lib/generators/gor/templates/main.go +29 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bf87cd74390e6eda98fa3fd0f463803699abba3a
|
4
|
+
data.tar.gz: 6e4a785e95fde8e7d0bac8667663642a98a157f3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1f9dd6bcc8a2548005c93a18542694f2b9113d28ff8b9010ef3cdc19b9b1fe7fb1cdaeeb51e93e97600f0815d9f77ee95f5441ed5ed35e441c81df950f9df6b8
|
7
|
+
data.tar.gz: 2d0f3af07182f02f4dff820bfe276b8bb0174711badc71aeffc302eb11dc28464d33e7b2a31e1776f6e7f589cd8f1e85118181719d2644bd8bdc97ff9ca7d8a9
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 B1nj0y <idegorepl@gmail.com>
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
go-on-rails
|
2
|
+
====
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
``ruby
|
9
|
+
gem 'go-on-rails'
|
10
|
+
``
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
``bash
|
14
|
+
$ bundle
|
15
|
+
``
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
``bash
|
19
|
+
$ gem install go-on-rails
|
20
|
+
``
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
go-on-rails is a Rails generator used to generate Golang codes from your ever running Rails app or an application that you would create with familiar Rails command tools. One or more examples will be given later on.
|
25
|
+
|
26
|
+
So you must have a Rails app or to create one before you can use go-on-rails generator to convert a Rails app to Golang codes.
|
27
|
+
|
28
|
+
You can basically run the command to convert the application:
|
29
|
+
|
30
|
+
``ruby
|
31
|
+
rails g gor [dev(elopment) | pro(duction) | test]
|
32
|
+
``
|
33
|
+
|
34
|
+
About more command details, you can run:
|
35
|
+
|
36
|
+
``ruby
|
37
|
+
rails g gor --help
|
38
|
+
``
|
39
|
+
|
40
|
+
And the gem is still under development, so there're a lot of known issues.
|
41
|
+
|
42
|
+
## Known issues and TODOs
|
43
|
+
|
44
|
+
* the generated Golang codes includes the association between models, basic relations like has_many, has_one, belongs_to have been supported
|
45
|
+
* so some association functions is available
|
46
|
+
* and the :dependent action is triggered when destroying some related model
|
47
|
+
* but the :through keyword not supported yet
|
48
|
+
* databases specific functions between mysql, postgres are not covered yet
|
49
|
+
* model callbacks in not available
|
50
|
+
|
51
|
+
Really a lot...
|
52
|
+
|
53
|
+
## Acknowledgement
|
54
|
+
|
55
|
+
When I had the idea to convert Rails app or build Golang app with Rails tools, I searched github and found the project: https://github.com/t-k/ar2gostruct. And from ar2gostruct I copied some codes on handling data structure convertion and models association, it make my idea come true faster than I imagined.
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
|
59
|
+
- Fork the project.
|
60
|
+
- Make your feature addition or bug fix.
|
61
|
+
- Add tests for it. This is important so I don't break it in a future version unintentionally.
|
62
|
+
- Commit, do not mess with Rakefile or version (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
63
|
+
- Send me a pull request. Bonus points for topic branches.
|
64
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Description:
|
2
|
+
generate Golang app by Rails models: use Rails as a model and migration tool to build a Golang app, or migrate some of existed Rails APIs to Golang to decouple and high-perform your services.
|
3
|
+
|
4
|
+
read more: https://github.com/gingerhot/goonrails
|
5
|
+
|
6
|
+
|
7
|
+
Example:
|
8
|
+
rails generate gor development -m user post
|
9
|
+
|
10
|
+
Here are valid ENV_NAME arguments: [dev, development, pro, production, test], the default ENV_NAME is "development" if you omit it.
|
11
|
+
|
12
|
+
So you can also run:
|
13
|
+
|
14
|
+
rails g gor dev -m user post
|
15
|
+
|
16
|
+
This will mainly create:
|
17
|
+
go_app/main.go
|
18
|
+
go_app/db/conn.go
|
19
|
+
go_app/models/user/gor_user.go
|
20
|
+
go_app/models/user/gor_post.go
|
21
|
+
|
22
|
+
Notice: If you omit the -m option, all the models of the Rails app will be generated.
|
23
|
+
|
24
|
+
So if you omit all the options, just run:
|
25
|
+
|
26
|
+
rails g gor
|
27
|
+
|
28
|
+
This will generate all the models and database connection with Rails development env params.
|
29
|
+
|
30
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module GoOnRails
|
2
|
+
class Association
|
3
|
+
def initialize(klass, models, max_col_size, max_type_size)
|
4
|
+
@klass = klass
|
5
|
+
@models = models
|
6
|
+
@max_col_size = max_col_size
|
7
|
+
@max_type_size = max_type_size
|
8
|
+
end
|
9
|
+
attr_reader :klass, :models, :max_col_size, :max_type_size
|
10
|
+
|
11
|
+
def get_schema_info
|
12
|
+
info = {struct_body: "", assoc_info: {has_many: {}, has_one: {}, belongs_to: {}}}
|
13
|
+
self.klass.reflect_on_all_associations.each do |assoc|
|
14
|
+
tags = ["json:\"#{assoc.name.to_s}\" db:\"#{assoc.name.to_s}\""]
|
15
|
+
case assoc.macro
|
16
|
+
when :has_many
|
17
|
+
col_name = assoc.name.to_s.camelize
|
18
|
+
class_name = assoc.name.to_s.singularize.camelize
|
19
|
+
unless assoc.options.empty?
|
20
|
+
class_name = assoc.options[:class_name] if assoc.options.key? :class_name
|
21
|
+
end
|
22
|
+
type_name = "[]#{class_name}"
|
23
|
+
info[:assoc_info][:has_many][col_name] = {class_name: class_name}
|
24
|
+
info[:assoc_info][:has_many][col_name].merge!(assoc.options) unless assoc.options.empty?
|
25
|
+
|
26
|
+
when :has_one, :belongs_to
|
27
|
+
col_name = class_name = assoc.name.to_s.camelize
|
28
|
+
class_name = assoc.options[:class_name] if assoc.options.key? :class_name unless assoc.options.empty?
|
29
|
+
type_name = class_name
|
30
|
+
info[:assoc_info][assoc.macro][col_name] = {class_name: class_name}
|
31
|
+
info[:assoc_info][assoc.macro][col_name].merge!(assoc.options) unless assoc.options.empty?
|
32
|
+
end
|
33
|
+
if col_name && type_name && (self.models.include? class_name)
|
34
|
+
format = "\t%-#{max_col_size}.#{max_col_size+2}s%-#{max_type_size}.#{max_type_size}s`%s`\n"
|
35
|
+
info[:struct_body] << sprintf(format, col_name, type_name, tags.join(" "))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
info
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module GoOnRails
|
2
|
+
class Convertor
|
3
|
+
TYPE_MAP = {
|
4
|
+
"string" => "string",
|
5
|
+
"text" => "string",
|
6
|
+
"boolean" => "bool",
|
7
|
+
"integer(1)" => "int8",
|
8
|
+
"integer(2)" => "int16",
|
9
|
+
"integer(3)" => "int32",
|
10
|
+
"integer(4)" => "int64",
|
11
|
+
"integer(8)" => "int64",
|
12
|
+
"float" => "float64",
|
13
|
+
"datetime" => "time.Time",
|
14
|
+
"date" => "time.Time"
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(klass, models, option = {})
|
18
|
+
@klass = klass
|
19
|
+
@models = models
|
20
|
+
@max_col_size = 0
|
21
|
+
@max_type_size = 0
|
22
|
+
end
|
23
|
+
attr_accessor :klass, :models, :max_col_size, :max_type_size
|
24
|
+
|
25
|
+
def convert
|
26
|
+
get_schema_info
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def get_schema_info
|
32
|
+
struct_info = {col_names: [], timestamp_cols: [], has_datetime_type: false, struct_body: ""}
|
33
|
+
|
34
|
+
self.max_col_size = get_max_col_size
|
35
|
+
self.max_type_size = get_max_type_size
|
36
|
+
|
37
|
+
self.klass.columns.each_with_index do |col, index|
|
38
|
+
tags = []
|
39
|
+
|
40
|
+
# add struct tag
|
41
|
+
tags << struct_tag(col)
|
42
|
+
|
43
|
+
col_type = col.type.to_s
|
44
|
+
struct_info[:has_datetime_type] = true if %w(datetime time).include? col_type
|
45
|
+
if col_type == "datetime" and %w(created_at updated_at).include? col.name
|
46
|
+
struct_info[:timestamp_cols] << col.name
|
47
|
+
end
|
48
|
+
|
49
|
+
case col_type
|
50
|
+
when "integer"
|
51
|
+
type = TYPE_MAP["integer(#{col.limit})"] || "int64"
|
52
|
+
type = "u#{type}" if col.sql_type.match("unsigned").present?
|
53
|
+
else
|
54
|
+
type = TYPE_MAP[col_type] || "string"
|
55
|
+
end
|
56
|
+
|
57
|
+
format = (index == 0 ? "" : "\t") + "%-#{self.max_col_size}.#{self.max_col_size}s%-#{self.max_type_size}.#{self.max_type_size}s`%s`\n"
|
58
|
+
struct_info[:col_names] << col.name unless col.name == "id"
|
59
|
+
struct_info[:struct_body] << sprintf(format, col.name.camelize, type, tags.join(" "))
|
60
|
+
end
|
61
|
+
|
62
|
+
assoc = get_associations
|
63
|
+
struct_info[:struct_body] << assoc[:struct_body]
|
64
|
+
struct_info[:assoc_info] = assoc[:assoc_info]
|
65
|
+
return struct_info
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_max_col_size
|
69
|
+
col_name_max_size = self.klass.column_names.collect{|name| name.size}.max || 0
|
70
|
+
assoc_max_size = self.klass.reflect_on_all_associations.collect{|assoc| assoc.name.to_s.size}.max || 0
|
71
|
+
type_max_size = TYPE_MAP.collect{|key, value| key.size}.max || 0
|
72
|
+
[col_name_max_size + 1, assoc_max_size, type_max_size].max
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_max_type_size
|
76
|
+
assoc_max_size = self.klass.reflect_on_all_associations.collect{|assoc| assoc.name.to_s.size + 2}.max || 0
|
77
|
+
type_max_size = TYPE_MAP.collect{|key, value| key.size}.max || 0
|
78
|
+
[assoc_max_size, type_max_size].max
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_struct_name
|
82
|
+
self.klass.table_name.camelize
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_associations
|
86
|
+
builder = GoOnRails::Association.new(self.klass, self.models, self.max_col_size, self.max_type_size)
|
87
|
+
builder.get_schema_info
|
88
|
+
end
|
89
|
+
|
90
|
+
def struct_tag(col)
|
91
|
+
"json:\"#{col.name}\" db:\"#{col.name}\""
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
require_relative 'association'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class GorGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
argument :env_name, type: :string, default: "development"
|
4
|
+
class_option :models, type: :array, default: [], aliases: '-m'
|
5
|
+
class_option :only_models, type: :boolean, default: false, aliases: '-o', description: "only generate models"
|
6
|
+
|
7
|
+
def generate_gor
|
8
|
+
env_names = %W(dev development pro production test)
|
9
|
+
unless env_names.include? env_name
|
10
|
+
printf("Invalid env argument: Not any of %p\n\n", env_names)
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
|
14
|
+
rails_env = case env_name
|
15
|
+
when "dev"
|
16
|
+
"development"
|
17
|
+
when "pro"
|
18
|
+
"production"
|
19
|
+
else
|
20
|
+
env_name
|
21
|
+
end
|
22
|
+
|
23
|
+
models = options[:models]
|
24
|
+
if models.empty?
|
25
|
+
models = get_all_models "app/models"
|
26
|
+
else
|
27
|
+
models.map!(&:camelize)
|
28
|
+
end
|
29
|
+
puts "The models: #{models} and Rails env [#{rails_env}] will be used to generate Golang App!"
|
30
|
+
|
31
|
+
models.each do |m|
|
32
|
+
begin
|
33
|
+
klass = m.split('::').inject(Object) { |kls, part| kls.const_get(part) }
|
34
|
+
if klass < ActiveRecord::Base && !klass.abstract_class?
|
35
|
+
@model_name = klass.to_s
|
36
|
+
convertor = GoOnRails::Convertor.new(klass, models)
|
37
|
+
@struct_info = convertor.convert
|
38
|
+
template "gor_model.go.erb", "go_app/models/gor_#{@model_name.underscore}.go"
|
39
|
+
end
|
40
|
+
rescue Exception => e
|
41
|
+
puts "Failed to convert the model [#{m}]: #{e.message}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
unless options[:only_models]
|
46
|
+
# generate the main.go
|
47
|
+
copy_file "main.go", "go_app/main.go"
|
48
|
+
|
49
|
+
# generate program for database connection
|
50
|
+
@db_config = {}
|
51
|
+
create_database_config(rails_env)
|
52
|
+
template "db.go.erb", "go_app/models/db.go"
|
53
|
+
|
54
|
+
# generate the controllers and views dir
|
55
|
+
copy_file "home_controller.go", "go_app/controllers/home_controller.go"
|
56
|
+
copy_file "index.tmpl", "go_app/views/index.tmpl"
|
57
|
+
copy_file "favicon.ico", "go_app/public/favicon.ico"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def get_all_models model_dir
|
64
|
+
Dir.chdir(model_dir) do
|
65
|
+
Dir["**/*.rb"]
|
66
|
+
end.map { |m| m.sub(/\.rb$/,'').camelize }
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_database_config rails_env
|
70
|
+
db_conf = Rails.configuration.database_configuration[rails_env]
|
71
|
+
case db_conf["adapter"]
|
72
|
+
when "sqlite3"
|
73
|
+
@db_config[:driver_name] = "sqlite3"
|
74
|
+
@db_config[:dsn] = "../" + db_conf["database"]
|
75
|
+
@db_config[:driver_package] = "_ \"github.com/mattn/go-sqlite3\""
|
76
|
+
when "mysql2"
|
77
|
+
@db_config[:driver_name] = "mysql"
|
78
|
+
# MySQL DSN format: username:password@protocol(address)/dbname?param=value
|
79
|
+
# See more: https://github.com/go-sql-driver/mysql
|
80
|
+
format = "%s:%s@%s/%s?charset=%s&parseTime=True&loc=Local"
|
81
|
+
@db_config[:dsn] = sprintf(format, *db_conf.values_at("username", "password", "host", "database", "encoding"))
|
82
|
+
@db_config[:driver_package] = "_ \"github.com/go-sql-driver/mysql\""
|
83
|
+
when "postgresql"
|
84
|
+
@db_config[:driver_name] = "postgres"
|
85
|
+
format = "host=%s user=%s dbname=%s sslmode=disable password=%s"
|
86
|
+
@db_config[:dsn] = sprintf(format, *db_conf.values_at("host", "username", "database", "password"))
|
87
|
+
@db_config[:driver_package] = "_ \"github.com/lib/pq\""
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
require_relative 'go_on_rails/converter'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
package model
|
2
|
+
|
3
|
+
import (
|
4
|
+
"log"
|
5
|
+
|
6
|
+
<%= @db_config[:driver_package] %>
|
7
|
+
"github.com/jmoiron/sqlx"
|
8
|
+
)
|
9
|
+
|
10
|
+
var db *sqlx.DB
|
11
|
+
|
12
|
+
func init() {
|
13
|
+
var err error
|
14
|
+
driver_name := "<%= @db_config[:driver_name] %>"
|
15
|
+
if driver_name == "" {
|
16
|
+
log.Fatal("Invalid driver name")
|
17
|
+
}
|
18
|
+
dsn := "<%= @db_config[:dsn] %>"
|
19
|
+
if dsn == "" {
|
20
|
+
log.Fatal("Invalid DSN")
|
21
|
+
}
|
22
|
+
db, err = sqlx.Connect(driver_name, dsn)
|
23
|
+
if err != nil {
|
24
|
+
log.Fatal(err)
|
25
|
+
}
|
26
|
+
}
|
File without changes
|
@@ -0,0 +1,451 @@
|
|
1
|
+
<%- param_name_plural = table_name = @model_name.underscore.pluralize -%>
|
2
|
+
<%- model_name_underscore = @model_name.underscore -%>
|
3
|
+
<%- col_names = @struct_info[:col_names] -%>
|
4
|
+
// The file is generated by go_on_rails, a Rails generator gem:
|
5
|
+
// https://rubygems.org/gems/go_on_rails
|
6
|
+
// By B1nj0y <idegorepl@gmail.com>
|
7
|
+
package model
|
8
|
+
|
9
|
+
import (
|
10
|
+
"errors"
|
11
|
+
"fmt"
|
12
|
+
"log"
|
13
|
+
"strings"
|
14
|
+
<%- if @struct_info[:has_datetime_type] -%>
|
15
|
+
"time"
|
16
|
+
<%- end -%>
|
17
|
+
)
|
18
|
+
|
19
|
+
type <%= @model_name %> struct {
|
20
|
+
<%= @struct_info[:struct_body] -%>
|
21
|
+
}
|
22
|
+
|
23
|
+
// Find<%= @model_name %> find a single <%= model_name_underscore %> by an id
|
24
|
+
func Find<%= @model_name %>(id int64) (*<%= @model_name %>, error) {
|
25
|
+
if id == 0 {
|
26
|
+
return nil, errors.New("Invalid id: it can't be zero")
|
27
|
+
}
|
28
|
+
var_<%= model_name_underscore %> := <%= @model_name %>{}
|
29
|
+
err := db.Get(&var_<%= model_name_underscore %>, "SELECT * FROM <%= table_name %> WHERE id = $1 LIMIT 1", id)
|
30
|
+
if err != nil {
|
31
|
+
log.Printf("Error: %v\n", err)
|
32
|
+
return nil, err
|
33
|
+
}
|
34
|
+
return &var_<%= model_name_underscore %>, nil
|
35
|
+
}
|
36
|
+
|
37
|
+
// Find<%= @model_name.pluralize %> find one or more <%= model_name_underscore.pluralize %> by one or more ids
|
38
|
+
func Find<%= @model_name.pluralize %>(ids ...int64) ([]<%= @model_name %>, error) {
|
39
|
+
if len(ids) == 0 {
|
40
|
+
msg := "At least one or more ids needed"
|
41
|
+
log.Println(msg)
|
42
|
+
return nil, errors.New(msg)
|
43
|
+
}
|
44
|
+
var_<%= param_name_plural %> := []<%= @model_name %>{}
|
45
|
+
idsStr := strings.Trim(strings.Replace(fmt.Sprint(ids), " ", ",", -1), "[]")
|
46
|
+
sql := fmt.Sprintf(`SELECT * FROM <%= table_name %> WHERE id IN (%s)`, idsStr)
|
47
|
+
err := db.Select(&var_<%= param_name_plural %>, sql)
|
48
|
+
if err != nil {
|
49
|
+
log.Printf("Error: %v\n", err)
|
50
|
+
return nil, err
|
51
|
+
}
|
52
|
+
return var_<%= param_name_plural %>, nil
|
53
|
+
}
|
54
|
+
|
55
|
+
// Find<%= @model_name %>By find a single <%= model_name_underscore %> by a field name and a value
|
56
|
+
func Find<%= @model_name %>By(field string, val interface{}) (*<%= @model_name %>, error) {
|
57
|
+
var_<%= model_name_underscore %> := <%= @model_name %>{}
|
58
|
+
sqlFmt := `SELECT * FROM <%= table_name %> WHERE %s = $1 LIMIT 1`
|
59
|
+
sqlStr := fmt.Sprintf(sqlFmt, field)
|
60
|
+
err := db.Get(&var_<%= model_name_underscore %>, sqlStr, val)
|
61
|
+
if err != nil {
|
62
|
+
log.Printf("Error: %v\n", err)
|
63
|
+
return nil, err
|
64
|
+
}
|
65
|
+
return &var_<%= model_name_underscore %>, nil
|
66
|
+
}
|
67
|
+
|
68
|
+
// Find<%= @model_name.pluralize %>By find all <%= param_name_plural %> by a field name and a value
|
69
|
+
func Find<%= @model_name.pluralize %>By(field string, val interface{}) (var_<%= param_name_plural %> []<%= @model_name %>, err error) {
|
70
|
+
sqlFmt := `SELECT * FROM <%= table_name %> WHERE %s = $1`
|
71
|
+
sqlStr := fmt.Sprintf(sqlFmt, field)
|
72
|
+
err = db.Select(&var_<%= param_name_plural %>, sqlStr, val)
|
73
|
+
if err != nil {
|
74
|
+
log.Printf("Error: %v\n", err)
|
75
|
+
return nil, err
|
76
|
+
}
|
77
|
+
return var_<%= param_name_plural %>, nil
|
78
|
+
}
|
79
|
+
|
80
|
+
// All<%= @model_name.pluralize %> get all the <%= @model_name %> records
|
81
|
+
func All<%= @model_name.pluralize %>() (<%= param_name_plural %> []<%= @model_name %>, err error) {
|
82
|
+
err = db.Select(&<%= table_name %>, "SELECT * FROM <%= table_name %>")
|
83
|
+
if err != nil {
|
84
|
+
log.Print(err)
|
85
|
+
return nil, err
|
86
|
+
}
|
87
|
+
return <%= param_name_plural %>, nil
|
88
|
+
}
|
89
|
+
|
90
|
+
// <%= @model_name %>Ids get all the Ids of <%= @model_name %> records
|
91
|
+
func <%= @model_name %>Ids() (ids []int64, err error) {
|
92
|
+
err = db.Select(&ids, "SELECT id FROM <%= table_name %>")
|
93
|
+
if err != nil {
|
94
|
+
log.Print(err)
|
95
|
+
return nil, err
|
96
|
+
}
|
97
|
+
return ids, nil
|
98
|
+
}
|
99
|
+
|
100
|
+
// <%= @model_name %>Ids get all the Ids of <%= @model_name %> records by where restriction
|
101
|
+
func <%= @model_name %>IdsWhere(where string, args ...interface{}) ([]int64, error) {
|
102
|
+
ids, err := <%= @model_name %>IntCol("id", where, args...)
|
103
|
+
return ids, err
|
104
|
+
}
|
105
|
+
|
106
|
+
// <%= @model_name %>IntCol get some int64 typed column of <%= @model_name %> by where restriction
|
107
|
+
func <%= @model_name %>IntCol(col, where string, args ...interface{}) (intColRecs []int64, err error) {
|
108
|
+
sql := "SELECT " + col + " FROM <%= table_name %>"
|
109
|
+
if len(where) > 0 {
|
110
|
+
sql = sql + " WHERE " + where
|
111
|
+
}
|
112
|
+
stmt, err := db.Preparex(sql)
|
113
|
+
if err != nil {
|
114
|
+
log.Print(err)
|
115
|
+
return nil, err
|
116
|
+
}
|
117
|
+
err = stmt.Select(&intColRecs, args...)
|
118
|
+
if err != nil {
|
119
|
+
log.Print(err)
|
120
|
+
return nil, err
|
121
|
+
}
|
122
|
+
return intColRecs, nil
|
123
|
+
}
|
124
|
+
|
125
|
+
// <%= @model_name %>StrCol get some string typed column of <%= @model_name %> by where restriction
|
126
|
+
func <%= @model_name %>StrCol(col, where string, args ...interface{}) (strColRecs []string, err error) {
|
127
|
+
sql := "SELECT " + col + " FROM <%= table_name %>"
|
128
|
+
if len(where) > 0 {
|
129
|
+
sql = sql + " WHERE " + where
|
130
|
+
}
|
131
|
+
stmt, err := db.Preparex(sql)
|
132
|
+
if err != nil {
|
133
|
+
log.Print(err)
|
134
|
+
return nil, err
|
135
|
+
}
|
136
|
+
err = stmt.Select(&strColRecs, args...)
|
137
|
+
if err != nil {
|
138
|
+
log.Print(err)
|
139
|
+
return nil, err
|
140
|
+
}
|
141
|
+
return strColRecs, nil
|
142
|
+
}
|
143
|
+
|
144
|
+
// Find<%= @model_name.pluralize %>Where query use a partial SQL clause that usually following after WHERE
|
145
|
+
// with placeholders, eg: FindUsersWhere("first_name = ? AND age > ?", "John", 18)
|
146
|
+
// will return those records in the table "users" whose first_name is "John" and age elder than 18
|
147
|
+
func Find<%= @model_name.pluralize %>Where(where string, args ...interface{}) (<%= param_name_plural %> []<%= @model_name %>, err error) {
|
148
|
+
sql := "SELECT * FROM <%= table_name %>"
|
149
|
+
if len(where) > 0 {
|
150
|
+
sql = sql + " WHERE " + where
|
151
|
+
}
|
152
|
+
stmt, err := db.Preparex(sql)
|
153
|
+
if err != nil {
|
154
|
+
log.Print(err)
|
155
|
+
return nil, err
|
156
|
+
}
|
157
|
+
err = stmt.Select(&<%= param_name_plural %>, args...)
|
158
|
+
if err != nil {
|
159
|
+
log.Print(err)
|
160
|
+
return nil, err
|
161
|
+
}
|
162
|
+
return <%= param_name_plural %>, nil
|
163
|
+
}
|
164
|
+
|
165
|
+
// Find<%= @model_name.pluralize %>BySql query use a complete SQL clause
|
166
|
+
// with placeholders, eg: FindUsersBySql("SELECT * FROM users WHERE first_name = ? AND age > ?", "John", 18)
|
167
|
+
// will return those records in the table "users" whose first_name is "John" and age elder than 18
|
168
|
+
func Find<%= @model_name.pluralize %>BySql(sql string, args ...interface{}) (<%= param_name_plural %> []<%= @model_name %>, err error) {
|
169
|
+
stmt, err := db.Preparex(sql)
|
170
|
+
if err != nil {
|
171
|
+
log.Print(err)
|
172
|
+
return nil, err
|
173
|
+
}
|
174
|
+
err = stmt.Select(&<%= param_name_plural %>, args...)
|
175
|
+
if err != nil {
|
176
|
+
log.Print(err)
|
177
|
+
return nil, err
|
178
|
+
}
|
179
|
+
return <%= param_name_plural %>, nil
|
180
|
+
}
|
181
|
+
|
182
|
+
func Create<%= @model_name %>(am map[string]interface{}) error {
|
183
|
+
if len(am) == 0 {
|
184
|
+
return fmt.Errorf("Zero key in the attributes map!")
|
185
|
+
}
|
186
|
+
<%- unless @struct_info[:timestamp_cols].empty? -%>
|
187
|
+
t := time.Now()
|
188
|
+
for _, v := range []string{<%= @struct_info[:timestamp_cols].map(&:inspect).join(", ") %>} {
|
189
|
+
if am[v] == nil {
|
190
|
+
am[v] = t
|
191
|
+
}
|
192
|
+
}
|
193
|
+
<%- end -%>
|
194
|
+
keys := make([]string, len(am))
|
195
|
+
i := 0
|
196
|
+
for k := range am {
|
197
|
+
keys[i] = k
|
198
|
+
i++
|
199
|
+
}
|
200
|
+
sqlFmt := `INSERT INTO <%= table_name %> (%s) VALUES (%s)`
|
201
|
+
sqlStr := fmt.Sprintf(sqlFmt, strings.Join(keys, ","), ":"+strings.Join(keys, ",:"))
|
202
|
+
_, err := db.NamedExec(sqlStr, am)
|
203
|
+
if err != nil {
|
204
|
+
log.Print(err)
|
205
|
+
return err
|
206
|
+
}
|
207
|
+
return nil
|
208
|
+
}
|
209
|
+
|
210
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Create() error {
|
211
|
+
<%- unless @struct_info[:timestamp_cols].empty? -%>
|
212
|
+
t := time.Now()
|
213
|
+
<%- @struct_info[:timestamp_cols].each do |c| -%>
|
214
|
+
var_<%= model_name_underscore %>.<%= c.camelize %> = t
|
215
|
+
<%- end -%>
|
216
|
+
<%- end -%>
|
217
|
+
sql := `INSERT INTO <%= table_name %> (<%= col_names.join(",") %>) VALUES (:<%= col_names.join(",:") %>)`
|
218
|
+
_, err := db.NamedExec(sql, var_<%= model_name_underscore %>)
|
219
|
+
return err
|
220
|
+
}
|
221
|
+
|
222
|
+
<%- unless @struct_info[:assoc_info][:has_many].empty? -%>
|
223
|
+
<%- has_many = @struct_info[:assoc_info][:has_many] -%>
|
224
|
+
<%- has_many.each do |k, v| -%>
|
225
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) <%= v[:class_name].pluralize %>Create(am map[string]interface{}) error {
|
226
|
+
<%- if v[:foreign_key] -%>
|
227
|
+
am["<%= v[:foreign_key] %>"] = var_<%= model_name_underscore %>.Id
|
228
|
+
<%- else -%>
|
229
|
+
am["<%= model_name_underscore %>_id"] = var_<%= model_name_underscore %>.Id
|
230
|
+
<%- end -%>
|
231
|
+
err := Create<%= v[:class_name] %>(am)
|
232
|
+
return err
|
233
|
+
}
|
234
|
+
|
235
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Get<%= v[:class_name].pluralize %>() error {
|
236
|
+
<%- if v[:foreign_key] -%>
|
237
|
+
var_<%= v[:class_name].underscore.pluralize %>, err := Find<%= v[:class_name].pluralize %>By("<%= v[:foreign_key] %>", var_<%= model_name_underscore %>.Id)
|
238
|
+
<%- else -%>
|
239
|
+
var_<%= v[:class_name].underscore.pluralize %>, err := Find<%= v[:class_name].pluralize %>By("<%= model_name_underscore %>_id", var_<%= model_name_underscore %>.Id)
|
240
|
+
<%- end -%>
|
241
|
+
if err == nil {
|
242
|
+
var_<%= model_name_underscore %>.<%= k %> = var_<%= v[:class_name].underscore.pluralize %>
|
243
|
+
}
|
244
|
+
return err
|
245
|
+
}
|
246
|
+
<%- end -%>
|
247
|
+
<%- end -%>
|
248
|
+
|
249
|
+
<%- unless @struct_info[:assoc_info][:has_one].empty? -%>
|
250
|
+
<%- has_one = @struct_info[:assoc_info][:has_one] -%>
|
251
|
+
<%- has_one.each do |k, v| -%>
|
252
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Create<%= v[:class_name] %>(am map[string]interface{}) error {
|
253
|
+
<%- if v[:foreign_key] -%>
|
254
|
+
am["<%= v[:foreign_key] %>"] = var_<%= model_name_underscore %>.Id
|
255
|
+
<%- else -%>
|
256
|
+
am["<%= model_name_underscore %>_id"] = var_<%= model_name_underscore %>.Id
|
257
|
+
<%- end -%>
|
258
|
+
err := Create<%= v[:class_name] %>(am)
|
259
|
+
return err
|
260
|
+
}
|
261
|
+
<%- end -%>
|
262
|
+
<%- end -%>
|
263
|
+
|
264
|
+
<%- unless @struct_info[:assoc_info][:belongs_to].empty? -%>
|
265
|
+
<%- belongs_to = @struct_info[:assoc_info][:belongs_to] -%>
|
266
|
+
<%- belongs_to.each do |k, v| -%>
|
267
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Create<%= v[:class_name] %>(am map[string]interface{}) error {
|
268
|
+
<%- if v[:foreign_key] -%>
|
269
|
+
am["<%= v[:foreign_key] %>"] = var_<%= model_name_underscore %>.Id
|
270
|
+
<%- else -%>
|
271
|
+
am["<%= model_name_underscore %>_id"] = var_<%= model_name_underscore %>.Id
|
272
|
+
<%- end -%>
|
273
|
+
err := Create<%= v[:class_name] %>(am)
|
274
|
+
return err
|
275
|
+
}
|
276
|
+
<%- end -%>
|
277
|
+
<%- end -%>
|
278
|
+
|
279
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Destroy() error {
|
280
|
+
if var_<%= model_name_underscore %>.Id == 0 {
|
281
|
+
return errors.New("Invalid Id field: it can't be a zero value")
|
282
|
+
}
|
283
|
+
err := Destroy<%= @model_name %>(var_<%= model_name_underscore %>.Id)
|
284
|
+
return err
|
285
|
+
}
|
286
|
+
|
287
|
+
func Destroy<%= @model_name %>(id int64) error {
|
288
|
+
stmt, err := db.Preparex(`DELETE FROM <%= table_name %> WHERE id = ?`)
|
289
|
+
_, err = stmt.Exec(id)
|
290
|
+
if err != nil {
|
291
|
+
return err
|
292
|
+
}
|
293
|
+
<%- [:has_many, :has_one].each do |ass| -%>
|
294
|
+
<%- ass_cols = @struct_info[:assoc_info][ass] -%>
|
295
|
+
<%- unless ass_cols.empty? -%>
|
296
|
+
<%- ass_cols.each_value do |opts| -%>
|
297
|
+
<%- if opts.key? :dependent -%>
|
298
|
+
<%- if opts.key? :foreign_key -%>
|
299
|
+
Destroy<%= opts[:class_name].pluralize %>Where("<%= opts[:foreign_key] %> = ?", id)
|
300
|
+
<%- else -%>
|
301
|
+
Destroy<%= opts[:class_name].pluralize %>Where("<%= model_name_underscore %>_id = ?", id)
|
302
|
+
<%- end -%>
|
303
|
+
<%- end -%>
|
304
|
+
<%- end -%>
|
305
|
+
<%- end -%>
|
306
|
+
<%- end -%>
|
307
|
+
return nil
|
308
|
+
}
|
309
|
+
|
310
|
+
func Destroy<%= @model_name.pluralize %>(ids ...int64) (int64, error) {
|
311
|
+
if len(ids) == 0 {
|
312
|
+
msg := "At least one or more ids needed"
|
313
|
+
log.Println(msg)
|
314
|
+
return 0, errors.New(msg)
|
315
|
+
}
|
316
|
+
idsStr := strings.Trim(strings.Replace(fmt.Sprint(ids), " ", ",", -1), "[]")
|
317
|
+
sql := fmt.Sprintf(`DELETE FROM <%= table_name %> WHERE id IN (%s)`, idsStr)
|
318
|
+
stmt, err := db.Preparex(sql)
|
319
|
+
result, err := stmt.Exec()
|
320
|
+
if err != nil {
|
321
|
+
return 0, err
|
322
|
+
}
|
323
|
+
cnt, err := result.RowsAffected()
|
324
|
+
if err != nil {
|
325
|
+
return 0, err
|
326
|
+
}
|
327
|
+
<%- [:has_many, :has_one].each do |ass| -%>
|
328
|
+
<%- ass_cols = @struct_info[:assoc_info][ass] -%>
|
329
|
+
<%- unless ass_cols.empty? -%>
|
330
|
+
<%- ass_cols.each_value do |opts| -%>
|
331
|
+
<%- if opts.key? :dependent -%>
|
332
|
+
<%- if opts.key? :foreign_key -%>
|
333
|
+
where := fmt.Sprintf("<%= opts[:foreign_key] %> IN (%s)", idsStr)
|
334
|
+
Destroy<%= opts[:class_name].pluralize %>Where(where)
|
335
|
+
<%- else -%>
|
336
|
+
where := fmt.Sprintf("<%= model_name_underscore %>_id IN (%s)", idsStr)
|
337
|
+
Destroy<%= opts[:class_name].pluralize %>Where(where)
|
338
|
+
<%- end -%>
|
339
|
+
<%- end -%>
|
340
|
+
<%- end -%>
|
341
|
+
<%- end -%>
|
342
|
+
<%- end -%>
|
343
|
+
return cnt, nil
|
344
|
+
}
|
345
|
+
|
346
|
+
// Destroy<%= @model_name.pluralize %>Where delete records by a where clause
|
347
|
+
// like: Destroy<%= @model_name.pluralize %>Where("name = ?", "John")
|
348
|
+
// And this func will not call the association dependent action
|
349
|
+
func Destroy<%= @model_name.pluralize %>Where(where string, args ...interface{}) (int64, error) {
|
350
|
+
sql := `DELETE FROM <%= table_name %> WHERE `
|
351
|
+
if len(where) > 0 {
|
352
|
+
sql = sql + where
|
353
|
+
} else {
|
354
|
+
return 0, errors.New("No WHERE conditions provided")
|
355
|
+
}
|
356
|
+
stmt, err := db.Preparex(sql)
|
357
|
+
result, err := stmt.Exec(args...)
|
358
|
+
if err != nil {
|
359
|
+
return 0, err
|
360
|
+
}
|
361
|
+
cnt, err := result.RowsAffected()
|
362
|
+
if err != nil {
|
363
|
+
return 0, err
|
364
|
+
}
|
365
|
+
return cnt, nil
|
366
|
+
}
|
367
|
+
|
368
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Save() error {
|
369
|
+
if var_<%= model_name_underscore %>.Id == 0 {
|
370
|
+
return errors.New("Invalid Id field: it can't be a zero value")
|
371
|
+
}
|
372
|
+
<%- if @struct_info[:timestamp_cols].include? "updated_at" -%>
|
373
|
+
var_<%= model_name_underscore %>.UpdatedAt = time.Now()
|
374
|
+
<%- end -%>
|
375
|
+
sqlFmt := `UPDATE <%= table_name %> SET %s WHERE id = %v`
|
376
|
+
sqlStr := fmt.Sprintf(sqlFmt, "<%= col_names.zip(col_names).map{|c| c.join(" = :")}.join(", ") %>", var_<%= model_name_underscore %>.Id)
|
377
|
+
_, err := db.NamedExec(sqlStr, var_<%= model_name_underscore %>)
|
378
|
+
return err
|
379
|
+
}
|
380
|
+
|
381
|
+
func Update<%= @model_name %>(id int64, am map[string]interface{}) error {
|
382
|
+
if len(am) == 0 {
|
383
|
+
return errors.New("Zero key in the attributes map!")
|
384
|
+
}
|
385
|
+
<%- if @struct_info[:timestamp_cols].include? "updated_at" -%>
|
386
|
+
am["updated_at"] = time.Now()
|
387
|
+
<%- end -%>
|
388
|
+
keys := make([]string, len(am))
|
389
|
+
i := 0
|
390
|
+
for k := range am {
|
391
|
+
keys[i] = k
|
392
|
+
i++
|
393
|
+
}
|
394
|
+
sqlFmt := `UPDATE <%= table_name %> SET %s WHERE id = %v`
|
395
|
+
setKeysArr := []string{}
|
396
|
+
for _,v := range keys {
|
397
|
+
s := fmt.Sprintf(" %s = :%s", v, v)
|
398
|
+
setKeysArr = append(setKeysArr, s)
|
399
|
+
}
|
400
|
+
sqlStr := fmt.Sprintf(sqlFmt, strings.Join(setKeysArr, ", "), id)
|
401
|
+
_, err := db.NamedExec(sqlStr, am)
|
402
|
+
if err != nil {
|
403
|
+
log.Print(err)
|
404
|
+
return err
|
405
|
+
}
|
406
|
+
return nil
|
407
|
+
}
|
408
|
+
|
409
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) Update(am map[string]interface{}) error {
|
410
|
+
if var_<%= model_name_underscore %>.Id == 0 {
|
411
|
+
return errors.New("Invalid Id field: it can't be a zero value")
|
412
|
+
}
|
413
|
+
err := Update<%= @model_name %>(var_<%= model_name_underscore %>.Id, am)
|
414
|
+
return err
|
415
|
+
}
|
416
|
+
|
417
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) UpdateAttributes(am map[string]interface{}) error {
|
418
|
+
if var_<%= model_name_underscore %>.Id == 0 {
|
419
|
+
return errors.New("Invalid Id field: it can't be a zero value")
|
420
|
+
}
|
421
|
+
err := Update<%= @model_name %>(var_<%= model_name_underscore %>.Id, am)
|
422
|
+
return err
|
423
|
+
}
|
424
|
+
|
425
|
+
func (var_<%= model_name_underscore %> *<%= @model_name %>) UpdateColumns(am map[string]interface{}) error {
|
426
|
+
if var_<%= model_name_underscore %>.Id == 0 {
|
427
|
+
return errors.New("Invalid Id field: it can't be a zero value")
|
428
|
+
}
|
429
|
+
err := Update<%= @model_name %>(var_<%= model_name_underscore %>.Id, am)
|
430
|
+
return err
|
431
|
+
}
|
432
|
+
|
433
|
+
func Update<%= @model_name.pluralize %>BySql(sql string, args ...interface{}) (int64, error) {
|
434
|
+
if sql == "" {
|
435
|
+
return 0, errors.New("A blank SQL clause")
|
436
|
+
}
|
437
|
+
<%- if @struct_info[:timestamp_cols].include? "updated_at" -%>
|
438
|
+
sql = strings.Replace(strings.ToLower(sql), "set", "set updated_at = ?, ", 1)
|
439
|
+
args = append([]interface{}{time.Now()}, args...)
|
440
|
+
<%- end -%>
|
441
|
+
stmt, err := db.Preparex(sql)
|
442
|
+
result, err := stmt.Exec(args...)
|
443
|
+
if err != nil {
|
444
|
+
return 0, err
|
445
|
+
}
|
446
|
+
cnt, err := result.RowsAffected()
|
447
|
+
if err != nil {
|
448
|
+
return 0, err
|
449
|
+
}
|
450
|
+
return cnt, nil
|
451
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
package controller
|
2
|
+
|
3
|
+
import (
|
4
|
+
"html/template"
|
5
|
+
"net/http"
|
6
|
+
// you can import models
|
7
|
+
//m "../models"
|
8
|
+
)
|
9
|
+
|
10
|
+
func HomeHandler(w http.ResponseWriter, r *http.Request) {
|
11
|
+
// you can use model functions to do CRUD
|
12
|
+
//
|
13
|
+
// user, _ := m.FindUser(1)
|
14
|
+
// u, err := json.Marshal(user)
|
15
|
+
// if err != nil {
|
16
|
+
// log.Printf("JSON encoding error: %v\n", err)
|
17
|
+
// u = []byte("Get data error!")
|
18
|
+
// }
|
19
|
+
|
20
|
+
type Greeting struct {
|
21
|
+
Name string
|
22
|
+
Words string
|
23
|
+
}
|
24
|
+
greeting := Greeting{Name: "Rubyist", Words: "Welcome to GoOnRails!"}
|
25
|
+
t, _ := template.ParseFiles("views/index.tmpl")
|
26
|
+
t.Execute(w, greeting)
|
27
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"flag"
|
5
|
+
"log"
|
6
|
+
"net/http"
|
7
|
+
"os"
|
8
|
+
|
9
|
+
c "./controllers"
|
10
|
+
"github.com/gorilla/handlers"
|
11
|
+
"github.com/gorilla/mux"
|
12
|
+
)
|
13
|
+
|
14
|
+
func main() {
|
15
|
+
// The app will run on port 3000 by default, you can custom it with the flag -port
|
16
|
+
servePort := flag.String("port", "3000", "Http Server Port")
|
17
|
+
flag.Parse()
|
18
|
+
log.Printf("The application starting on the port: [%v]\n", *servePort)
|
19
|
+
|
20
|
+
// Here we are instantiating the gorilla/mux router
|
21
|
+
r := mux.NewRouter()
|
22
|
+
// Then we bind some route to some handler(controller action)
|
23
|
+
r.HandleFunc("/", c.HomeHandler)
|
24
|
+
// Create a static assets router
|
25
|
+
r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))
|
26
|
+
|
27
|
+
// Let's start the server
|
28
|
+
http.ListenAndServe(":"+*servePort, handlers.LoggingHandler(os.Stdout, r))
|
29
|
+
}
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: go-on-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- B1nj0y
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Modeling, developing and testing your Golang app with your familiar Rails
|
14
|
+
tools like rails generate, db migration, console etc. And you can convert your ever
|
15
|
+
running Rails app to Golang app partially or completely(not now or your Rails app
|
16
|
+
not so complicated)
|
17
|
+
email: idegorepl@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- MIT-LICENSE
|
23
|
+
- README.md
|
24
|
+
- lib/generators/gor/USAGE
|
25
|
+
- lib/generators/gor/go_on_rails/association.rb
|
26
|
+
- lib/generators/gor/go_on_rails/converter.rb
|
27
|
+
- lib/generators/gor/gor_generator.rb
|
28
|
+
- lib/generators/gor/templates/db.go.erb
|
29
|
+
- lib/generators/gor/templates/favicon.ico
|
30
|
+
- lib/generators/gor/templates/gor_model.go.erb
|
31
|
+
- lib/generators/gor/templates/home_controller.go
|
32
|
+
- lib/generators/gor/templates/index.tmpl
|
33
|
+
- lib/generators/gor/templates/main.go
|
34
|
+
homepage: https://github.com/goonr/go-on-rails
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.5.2
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Use Rails generator to Generate a Golang application
|
58
|
+
test_files: []
|