go-on-rails 0.1.10 → 0.1.11
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.
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
|