go-on-rails 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3dc0eef63c002b0600a7b8593197776fa5d5efa
|
4
|
+
data.tar.gz: 899707b6d8f8be9734d0b8101533b73c3d2922f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0905ffeef7c809e4d7d92b1b8dced27cec08202636ac508a1e06310a0c0087c3858a6129862a97c19aaf60af071884bdbf57a6980090731ac3ef6eb15f24aa5
|
7
|
+
data.tar.gz: 8733f862097286d34da51f0b504951b980477d740ada46cf0b6c511457227032094c89d35b0c30c2e9a69cfcadab5839e5c69be9454694a17ecdde7154cfb605
|
data/README.md
CHANGED
@@ -14,7 +14,10 @@ go-on-rails is a Rails generator created for three scenarios:
|
|
14
14
|
2. Use your farmiliar Rails tools to develope and manage a Golang app project
|
15
15
|
3. Convert a *not very complicated* Rails app to Golang equivalent
|
16
16
|
|
17
|
-
Here's
|
17
|
+
Here's some examples:
|
18
|
+
* a simple [example(tutorial)](https://github.com/goonr/example_simple) on the basic usage of go-on-rails generator
|
19
|
+
* [An advanced example](https://github.com/goonr/example_with_admin) shows how to integrate Go APIs in a Rails project
|
20
|
+
* [Another example](https://github.com/goonr/example_read_rails_session) shows how to read a Rails session from a go-on-rails generated Go API
|
18
21
|
|
19
22
|
## Prerequisites
|
20
23
|
|
@@ -26,7 +29,7 @@ Here's a simple [example(tutorial)](https://github.com/goonr/example_simple) sho
|
|
26
29
|
Add this line to your application's Gemfile:
|
27
30
|
|
28
31
|
```ruby
|
29
|
-
gem 'go-on-rails', '~> 0.1.
|
32
|
+
gem 'go-on-rails', '~> 0.1.11'
|
30
33
|
```
|
31
34
|
|
32
35
|
And then execute:
|
@@ -11,14 +11,27 @@ module GoOnRails
|
|
11
11
|
"integer(8)" => "int64",
|
12
12
|
"float" => "float64",
|
13
13
|
"datetime" => "time.Time",
|
14
|
-
"date" => "time.Time"
|
15
|
-
|
14
|
+
"date" => "time.Time",
|
15
|
+
"inet" => "string"
|
16
|
+
}.freeze
|
16
17
|
|
17
|
-
|
18
|
+
# COALESCE datetime typed field for different databases
|
19
|
+
# FIXME: no idea for sqlite3 at present
|
20
|
+
DATETIME_COALESCE_MAP = {
|
21
|
+
"sqlite3" => "%s",
|
22
|
+
"mysql" => "COALESCE(%s, CONVERT_TZ('0001-01-01 00:00:00','+00:00','UTC')) AS %s",
|
23
|
+
"postgres" => "COALESCE(%s, (TIMESTAMP WITH TIME ZONE '0001-01-01 00:00:00+00') AT TIME ZONE 'UTC') AS %s"
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
# types need special treatment in the nullable_map() method
|
27
|
+
SPECIAL_COALESCE_TYPES = %w[inet].freeze
|
28
|
+
|
29
|
+
def initialize(klass, models, database)
|
18
30
|
@klass = klass
|
19
31
|
@models = models
|
32
|
+
@database = database
|
20
33
|
end
|
21
|
-
attr_accessor :klass, :models
|
34
|
+
attr_accessor :klass, :models, :database
|
22
35
|
|
23
36
|
def convert
|
24
37
|
get_schema_info
|
@@ -27,9 +40,16 @@ module GoOnRails
|
|
27
40
|
private
|
28
41
|
|
29
42
|
def get_schema_info
|
30
|
-
struct_info = {
|
43
|
+
struct_info = {
|
44
|
+
col_names: [],
|
45
|
+
timestamp_cols: [],
|
46
|
+
has_datetime_type: false,
|
47
|
+
struct_body: "",
|
48
|
+
}
|
31
49
|
|
32
50
|
validation = GoOnRails::Validator.new(self.klass)
|
51
|
+
# store fields by if nullable
|
52
|
+
fields = { yes: [], no: [] }
|
33
53
|
|
34
54
|
self.klass.columns.each_with_index do |col, index|
|
35
55
|
tags = []
|
@@ -51,6 +71,17 @@ module GoOnRails
|
|
51
71
|
type = TYPE_MAP[col_type] || "string"
|
52
72
|
end
|
53
73
|
|
74
|
+
# check the fields if nullable
|
75
|
+
if col.null == true
|
76
|
+
if SPECIAL_COALESCE_TYPES.include?(col_type)
|
77
|
+
fields[:yes] << [col.name, col_type]
|
78
|
+
else
|
79
|
+
fields[:yes] << [col.name, type]
|
80
|
+
end
|
81
|
+
else
|
82
|
+
fields[:no] << col.name
|
83
|
+
end
|
84
|
+
|
54
85
|
struct_info[:col_names] << col.name unless col.name == "id"
|
55
86
|
struct_info[:struct_body] << sprintf("%s %s `%s`\n", col.name.camelize, type, tags.join(" "))
|
56
87
|
end
|
@@ -59,6 +90,8 @@ module GoOnRails
|
|
59
90
|
struct_info[:struct_body] << assoc[:struct_body]
|
60
91
|
struct_info[:assoc_info] = assoc[:assoc_info]
|
61
92
|
struct_info[:has_assoc_dependent] = assoc[:has_assoc_dependent]
|
93
|
+
struct_info[:select_fields] = nullable_select_str(fields)
|
94
|
+
|
62
95
|
return struct_info
|
63
96
|
end
|
64
97
|
|
@@ -75,6 +108,36 @@ module GoOnRails
|
|
75
108
|
valid_tags = validation.build_validator_tag(col)
|
76
109
|
"json:\"#{col.name},omitempty\" db:\"#{col.name}\" #{valid_tags}"
|
77
110
|
end
|
111
|
+
|
112
|
+
def nullable_select_str(fields)
|
113
|
+
fields[:yes].map do |f|
|
114
|
+
sprintf(nullable_map(f[1]), "#{self.klass.table_name}.#{f[0]}", f[0])
|
115
|
+
end.concat(
|
116
|
+
fields[:no].map do |f|
|
117
|
+
sprintf("%s.%s", self.klass.table_name, f)
|
118
|
+
end
|
119
|
+
).join(", ")
|
120
|
+
end
|
121
|
+
|
122
|
+
def nullable_map(type)
|
123
|
+
case type
|
124
|
+
when "string"
|
125
|
+
"COALESCE(%s, '') AS %s"
|
126
|
+
when "int8", "int16", "int32", "int64"
|
127
|
+
"COALESCE(%s, 0) AS %s"
|
128
|
+
when "float64"
|
129
|
+
"COALESCE(%s, 0.0) AS %s"
|
130
|
+
when "bool"
|
131
|
+
"COALESCE(%s, FALSE) AS %s"
|
132
|
+
when "time.Time"
|
133
|
+
DATETIME_COALESCE_MAP[self.database]
|
134
|
+
when "inet"
|
135
|
+
"COALESCE(%s, '0.0.0.0') AS %s"
|
136
|
+
else
|
137
|
+
# FIXME: here just return the column name, may skip some nullable field and cause an error in a query
|
138
|
+
"%s"
|
139
|
+
end
|
140
|
+
end
|
78
141
|
end
|
79
142
|
end
|
80
143
|
|
@@ -33,21 +33,26 @@ class GorGenerator < Rails::Generators::Base
|
|
33
33
|
@db_config = {}
|
34
34
|
read_database_config(rails_env)
|
35
35
|
|
36
|
-
|
36
|
+
@all_structs_info = {}
|
37
|
+
# iterate the models to get all the structs' info
|
37
38
|
@models.each do |m|
|
38
39
|
begin
|
39
40
|
klass = m.split('::').inject(Object) { |kls, part| kls.const_get(part) }
|
40
41
|
if klass < ActiveRecord::Base && !klass.abstract_class?
|
41
|
-
|
42
|
-
|
43
|
-
@struct_info = convertor.convert
|
44
|
-
template "gor_model.go.erb", "go_app/models/gor_#{@model_name.underscore}.go"
|
42
|
+
convertor = GoOnRails::Convertor.new(klass, @models, @db_config[:driver_name])
|
43
|
+
@all_structs_info[klass.to_s] = convertor.convert
|
45
44
|
end
|
46
45
|
rescue Exception => e
|
47
46
|
puts "Failed to convert the model [#{m}]: #{e.message}"
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
50
|
+
# iterate the structs info to generate codes for each model
|
51
|
+
@all_structs_info.each do |k, v|
|
52
|
+
@model_name, @struct_info = k, v
|
53
|
+
template "gor_model.go.erb", "go_app/models/gor_#{@model_name.underscore}.go"
|
54
|
+
end
|
55
|
+
|
51
56
|
# generate program for database connection
|
52
57
|
template "db.go.erb", "go_app/models/db.go"
|
53
58
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
<%- var_pmn = table_name = @model_name.underscore.pluralize -%>
|
3
3
|
<%#- var_umn stands for underscored model name -#%>
|
4
4
|
<%- var_umn = @model_name.underscore -%>
|
5
|
+
<%- fields = @struct_info[:select_fields] -%>
|
5
6
|
<%- col_names = @struct_info[:col_names] -%>
|
6
7
|
<%- has_assoc = !@struct_info[:assoc_info][:has_many].empty? || !@struct_info[:assoc_info][:has_one].empty? -%>
|
7
8
|
// Package models includes the functions on the model <%= @model_name %>.
|
@@ -13,9 +14,9 @@ import (
|
|
13
14
|
"log"
|
14
15
|
"math"
|
15
16
|
"strings"
|
16
|
-
|
17
|
+
<%- if @struct_info[:has_datetime_type] -%>
|
17
18
|
"time"
|
18
|
-
|
19
|
+
<%- end -%>
|
19
20
|
|
20
21
|
"github.com/asaskevich/govalidator"
|
21
22
|
)
|
@@ -228,7 +229,7 @@ func Find<%= @model_name %>(id int64) (*<%= @model_name %>, error) {
|
|
228
229
|
return nil, errors.New("Invalid ID: it can't be zero")
|
229
230
|
}
|
230
231
|
_<%= var_umn %> := <%= @model_name %>{}
|
231
|
-
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT
|
232
|
+
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT <%= fields %> FROM <%= table_name %> WHERE <%= table_name %>.id = ? LIMIT 1`), id)
|
232
233
|
if err != nil {
|
233
234
|
log.Printf("Error: %v\n", err)
|
234
235
|
return nil, err
|
@@ -239,7 +240,7 @@ func Find<%= @model_name %>(id int64) (*<%= @model_name %>, error) {
|
|
239
240
|
// First<%= @model_name %> find the first one <%= var_umn %> by ID ASC order
|
240
241
|
func First<%= @model_name %>() (*<%= @model_name %>, error) {
|
241
242
|
_<%= var_umn %> := <%= @model_name %>{}
|
242
|
-
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT
|
243
|
+
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT <%= fields %> FROM <%= table_name %> ORDER BY <%= table_name %>.id ASC LIMIT 1`))
|
243
244
|
if err != nil {
|
244
245
|
log.Printf("Error: %v\n", err)
|
245
246
|
return nil, err
|
@@ -250,7 +251,7 @@ func First<%= @model_name %>() (*<%= @model_name %>, error) {
|
|
250
251
|
// First<%= @model_name.pluralize %> find the first N <%= var_umn.pluralize %> by ID ASC order
|
251
252
|
func First<%= @model_name.pluralize %>(n uint32) ([]<%= @model_name %>, error) {
|
252
253
|
_<%= var_pmn %> := []<%= @model_name %>{}
|
253
|
-
sql := fmt.Sprintf("SELECT
|
254
|
+
sql := fmt.Sprintf("SELECT <%= fields %> FROM <%= table_name %> ORDER BY <%= table_name %>.id ASC LIMIT %v", n)
|
254
255
|
err := DB.Select(&_<%= var_pmn %>, DB.Rebind(sql))
|
255
256
|
if err != nil {
|
256
257
|
log.Printf("Error: %v\n", err)
|
@@ -262,7 +263,7 @@ func First<%= @model_name.pluralize %>(n uint32) ([]<%= @model_name %>, error) {
|
|
262
263
|
// Last<%= @model_name %> find the last one <%= var_umn %> by ID DESC order
|
263
264
|
func Last<%= @model_name %>() (*<%= @model_name %>, error) {
|
264
265
|
_<%= var_umn %> := <%= @model_name %>{}
|
265
|
-
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT
|
266
|
+
err := DB.Get(&_<%= var_umn %>, DB.Rebind(`SELECT <%= fields %> FROM <%= table_name %> ORDER BY <%= table_name %>.id DESC LIMIT 1`))
|
266
267
|
if err != nil {
|
267
268
|
log.Printf("Error: %v\n", err)
|
268
269
|
return nil, err
|
@@ -273,7 +274,7 @@ func Last<%= @model_name %>() (*<%= @model_name %>, error) {
|
|
273
274
|
// Last<%= @model_name.pluralize %> find the last N <%= var_umn.pluralize %> by ID DESC order
|
274
275
|
func Last<%= @model_name.pluralize %>(n uint32) ([]<%= @model_name %>, error) {
|
275
276
|
_<%= var_pmn %> := []<%= @model_name %>{}
|
276
|
-
sql := fmt.Sprintf("SELECT
|
277
|
+
sql := fmt.Sprintf("SELECT <%= fields %> FROM <%= table_name %> ORDER BY <%= table_name %>.id DESC LIMIT %v", n)
|
277
278
|
err := DB.Select(&_<%= var_pmn %>, DB.Rebind(sql))
|
278
279
|
if err != nil {
|
279
280
|
log.Printf("Error: %v\n", err)
|
@@ -291,7 +292,7 @@ func Find<%= @model_name.pluralize %>(ids ...int64) ([]<%= @model_name %>, error
|
|
291
292
|
}
|
292
293
|
_<%= var_pmn %> := []<%= @model_name %>{}
|
293
294
|
idsHolder := strings.Repeat(",?", len(ids)-1)
|
294
|
-
sql := DB.Rebind(fmt.Sprintf(`SELECT
|
295
|
+
sql := DB.Rebind(fmt.Sprintf(`SELECT <%= fields %> FROM <%= table_name %> WHERE <%= table_name %>.id IN (?%s)`, idsHolder))
|
295
296
|
idsT := []interface{}{}
|
296
297
|
for _,id := range ids {
|
297
298
|
idsT = append(idsT, interface{}(id))
|
@@ -307,7 +308,7 @@ func Find<%= @model_name.pluralize %>(ids ...int64) ([]<%= @model_name %>, error
|
|
307
308
|
// Find<%= @model_name %>By find a single <%= var_umn %> by a field name and a value
|
308
309
|
func Find<%= @model_name %>By(field string, val interface{}) (*<%= @model_name %>, error) {
|
309
310
|
_<%= var_umn %> := <%= @model_name %>{}
|
310
|
-
sqlFmt := `SELECT
|
311
|
+
sqlFmt := `SELECT <%= fields %> FROM <%= table_name %> WHERE %s = ? LIMIT 1`
|
311
312
|
sqlStr := fmt.Sprintf(sqlFmt, field)
|
312
313
|
err := DB.Get(&_<%= var_umn %>, DB.Rebind(sqlStr), val)
|
313
314
|
if err != nil {
|
@@ -319,7 +320,7 @@ func Find<%= @model_name %>By(field string, val interface{}) (*<%= @model_name %
|
|
319
320
|
|
320
321
|
// Find<%= @model_name.pluralize %>By find all <%= var_pmn %> by a field name and a value
|
321
322
|
func Find<%= @model_name.pluralize %>By(field string, val interface{}) (_<%= var_pmn %> []<%= @model_name %>, err error) {
|
322
|
-
sqlFmt := `SELECT
|
323
|
+
sqlFmt := `SELECT <%= fields %> FROM <%= table_name %> WHERE %s = ?`
|
323
324
|
sqlStr := fmt.Sprintf(sqlFmt, field)
|
324
325
|
err = DB.Select(&_<%= var_pmn %>, DB.Rebind(sqlStr), val)
|
325
326
|
if err != nil {
|
@@ -331,7 +332,7 @@ func Find<%= @model_name.pluralize %>By(field string, val interface{}) (_<%= var
|
|
331
332
|
|
332
333
|
// All<%= @model_name.pluralize %> get all the <%= @model_name %> records
|
333
334
|
func All<%= @model_name.pluralize %>() (<%= var_pmn %> []<%= @model_name %>, err error) {
|
334
|
-
err = DB.Select(&<%= var_pmn %>, "SELECT
|
335
|
+
err = DB.Select(&<%= var_pmn %>, "SELECT <%= fields %> FROM <%= table_name %>")
|
335
336
|
if err != nil {
|
336
337
|
log.Println(err)
|
337
338
|
return nil, err
|
@@ -526,7 +527,7 @@ func <%= @model_name %>StrCol(col, where string, args ...interface{}) (strColRec
|
|
526
527
|
// with placeholders, eg: FindUsersWhere("first_name = ? AND age > ?", "John", 18)
|
527
528
|
// will return those records in the table "users" whose first_name is "John" and age elder than 18
|
528
529
|
func Find<%= @model_name.pluralize %>Where(where string, args ...interface{}) (<%= var_pmn %> []<%= @model_name %>, err error) {
|
529
|
-
sql := "SELECT
|
530
|
+
sql := "SELECT <%= fields %> FROM <%= table_name %>"
|
530
531
|
if len(where) > 0 {
|
531
532
|
sql = sql + " WHERE " + where
|
532
533
|
}
|
@@ -688,7 +689,7 @@ func <%= @model_name %>Get<%= k.pluralize %>(id int64) ([]<%= v[:class_name] %>,
|
|
688
689
|
// FIXME: use transaction to create these associated objects
|
689
690
|
<%- target_table = v[:class_name].underscore.pluralize -%>
|
690
691
|
<%- through_table = v[:through].to_s.pluralize -%>
|
691
|
-
sql := `SELECT <%=
|
692
|
+
sql := `SELECT <%= @all_structs_info[v[:class_name]][:select_fields] %>
|
692
693
|
FROM <%= target_table %>
|
693
694
|
INNER JOIN <%= through_table %>
|
694
695
|
ON <%= target_table %>.id = <%= through_table %>.<%= v[:class_name].underscore %>_id
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: go-on-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- B1nj0y
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Modeling, developing and testing your Golang app with your familiar Rails
|
14
14
|
tools like rails generate, db migration, console etc. It is more meant to help integrating
|