goa_model_gen 0.4.2 → 0.5.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.
- checksums.yaml +4 -4
- data/lib/goa_model_gen/cli.rb +10 -7
- data/lib/goa_model_gen/field.rb +18 -3
- data/lib/goa_model_gen/generator.rb +37 -1
- data/lib/goa_model_gen/loader.rb +2 -1
- data/lib/goa_model_gen/logger.rb +24 -0
- data/lib/goa_model_gen/source_file.rb +0 -19
- data/lib/goa_model_gen/templates/base.go.erb +9 -0
- data/lib/goa_model_gen/templates/converter.go.erb +15 -16
- data/lib/goa_model_gen/templates/converter_base.go.erb +9 -8
- data/lib/goa_model_gen/templates/goon.go.erb +7 -6
- data/lib/goa_model_gen/templates/model.go.erb +8 -224
- data/lib/goa_model_gen/templates/model_store.go.erb +222 -0
- data/lib/goa_model_gen/templates/model_validation.go.erb +2 -5
- data/lib/goa_model_gen/type.rb +5 -1
- data/lib/goa_model_gen/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0cacd5ba7fc52902ba68ae788e6e4ec5a50fb6dd663da221d995c81b425f560
|
4
|
+
data.tar.gz: 71368a7fdecfbdac2cc28168df06f583891833f8067c662323576ff58060fd87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70e0595b798469b555cf54c3fd277c5768a4ca3972a1654ec345c3d95d68cee0657fea988e43e27a8aed168ca7e360fb840a8ca8a3ca2f14aa23d81ffd74b649
|
7
|
+
data.tar.gz: 9d3390c47308bada677ce7ed720fa39984a86013a49d0c0c010cec95c7e77c41ace145137d988f80206d32a814e0f433bce9ac971b918135e05893c93a3985bd
|
data/lib/goa_model_gen/cli.rb
CHANGED
@@ -2,6 +2,7 @@ require "goa_model_gen"
|
|
2
2
|
|
3
3
|
require "thor"
|
4
4
|
|
5
|
+
require "goa_model_gen/logger"
|
5
6
|
require "goa_model_gen/config"
|
6
7
|
require "goa_model_gen/loader"
|
7
8
|
require "goa_model_gen/generator"
|
@@ -9,17 +10,18 @@ require "goa_model_gen/generator"
|
|
9
10
|
module GoaModelGen
|
10
11
|
class Cli < Thor
|
11
12
|
class_option :version, type: :boolean, aliases: 'v', desc: 'Show version before processing'
|
13
|
+
class_option :log_level, type: :string, aliases: 'l', desc: 'Log level, one of debug,info,warn,error,fatal. The default value is info'
|
12
14
|
class_option :config, type: :string, aliases: 'c', default: './goa_model_gen.yaml', desc: 'Path to config file. You can generate it by config subcommand'
|
13
15
|
|
14
16
|
desc "config", "Generate config file"
|
15
17
|
def config(path = './goa_model_gen.yaml')
|
16
|
-
|
18
|
+
setup
|
17
19
|
open(path, 'w'){|f| f.puts(Config.new.fulfill.to_yaml) }
|
18
20
|
end
|
19
21
|
|
20
22
|
desc "bootstrap", "Generate files not concerned with model"
|
21
23
|
def bootstrap
|
22
|
-
|
24
|
+
setup
|
23
25
|
generator = new_generator
|
24
26
|
{
|
25
27
|
"templates/goon.go.erb" => "model/goon.go",
|
@@ -31,7 +33,7 @@ module GoaModelGen
|
|
31
33
|
|
32
34
|
desc "show FILE1...", "Show model info from definition files"
|
33
35
|
def show(*paths)
|
34
|
-
|
36
|
+
setup
|
35
37
|
load_types_for(paths) do |source_file|
|
36
38
|
puts "types in #{source_file.yaml_path}"
|
37
39
|
puts YAML.dump(source_file.types)
|
@@ -40,14 +42,14 @@ module GoaModelGen
|
|
40
42
|
|
41
43
|
desc "model FILE1...", "Generate model files from definition files"
|
42
44
|
def model(*paths)
|
43
|
-
|
45
|
+
setup
|
44
46
|
load_types_for(paths) do |source_file|
|
45
47
|
generator = new_generator.tap{|g| g.source_file = source_file }
|
46
48
|
[
|
47
49
|
{path: 'templates/model.go.erb', suffix: '.go', overwrite: true},
|
48
50
|
{path: 'templates/model_validation.go.erb', suffix: '_validation.go', overwrite: false},
|
49
51
|
].each do |d|
|
50
|
-
dest = File.join(cfg.model_dir, File.basename(source_file.
|
52
|
+
dest = File.join(cfg.model_dir, File.basename(source_file.yaml_path, ".*") + d[:suffix])
|
51
53
|
generator.run(d[:path], dest, overwrite: d[:overwrite])
|
52
54
|
end
|
53
55
|
end
|
@@ -55,7 +57,7 @@ module GoaModelGen
|
|
55
57
|
|
56
58
|
desc "converter FILE1...", "Generate converter files from definition files and swagger.yaml"
|
57
59
|
def converter(*paths)
|
58
|
-
|
60
|
+
setup
|
59
61
|
load_types_for(paths) do |source_file|
|
60
62
|
generator = new_generator.tap{|g| g.source_file = source_file }
|
61
63
|
dest = File.join(cfg.controller_dir, File.basename(source_file.yaml_path, ".*") + "_conv.go")
|
@@ -71,8 +73,9 @@ module GoaModelGen
|
|
71
73
|
end
|
72
74
|
|
73
75
|
no_commands do
|
74
|
-
def
|
76
|
+
def setup
|
75
77
|
show_version if options[:version]
|
78
|
+
GoaModelGen::Logger.setup(options[:log_level] || 'info')
|
76
79
|
end
|
77
80
|
|
78
81
|
def show_version
|
data/lib/goa_model_gen/field.rb
CHANGED
@@ -9,6 +9,8 @@ module GoaModelGen
|
|
9
9
|
attr_reader :name, :type, :default
|
10
10
|
attr_accessor :format # for swagger. See https://swagger.io/docs/specification/data-models/data-types/
|
11
11
|
attr_accessor :required
|
12
|
+
attr_accessor :validation
|
13
|
+
attr_accessor :swagger_name
|
12
14
|
attr_reader :type_obj
|
13
15
|
attr_reader :datastore_tag
|
14
16
|
|
@@ -18,6 +20,9 @@ module GoaModelGen
|
|
18
20
|
@format = attrs['format']
|
19
21
|
@required = attrs['required']
|
20
22
|
@default = attrs['default']
|
23
|
+
@validation = attrs['validation']
|
24
|
+
@goa_name = attrs['goa_name']
|
25
|
+
@swagger_name = attrs['swagger_name']
|
21
26
|
@datastore_tag = attrs['datastore_tag']
|
22
27
|
end
|
23
28
|
|
@@ -25,7 +30,11 @@ module GoaModelGen
|
|
25
30
|
PRIMITIVE_TYPES = %w[bool int int64 float string time.Time uuid.UUID *datastore.Key]
|
26
31
|
|
27
32
|
def goa_name
|
28
|
-
Goa.capitalize_join(
|
33
|
+
@goa_name.presence || Goa.capitalize_join(swagger_name.split("_"))
|
34
|
+
end
|
35
|
+
|
36
|
+
def swagger_name
|
37
|
+
@swagger_name.presence ||name.underscore
|
29
38
|
end
|
30
39
|
|
31
40
|
def primitive?
|
@@ -54,10 +63,12 @@ module GoaModelGen
|
|
54
63
|
def tag
|
55
64
|
json_tag = name.underscore.dup
|
56
65
|
json_tag << ',omitempty' if nullable?
|
57
|
-
|
66
|
+
validate_tags = nullable? ? [] : ['required']
|
67
|
+
validate_tags << validation.presence
|
68
|
+
validate_tags.compact!
|
58
69
|
[
|
59
70
|
['json', json_tag],
|
60
|
-
['validate',
|
71
|
+
['validate', validate_tags.join(',').presence],
|
61
72
|
['datastore', datastore_tag],
|
62
73
|
].map{|k,v| v ? "#{k}:\"#{v}\"" : nil}.compact.join(' ')
|
63
74
|
end
|
@@ -66,6 +77,10 @@ module GoaModelGen
|
|
66
77
|
"#{ name } #{ type } `#{ tag }`"
|
67
78
|
end
|
68
79
|
|
80
|
+
def type_package
|
81
|
+
type.include?('.') ? type.split('.', 2).first.sub(/\A\*/, '') : nil
|
82
|
+
end
|
83
|
+
|
69
84
|
# https://swagger.io/docs/specification/data-models/data-types/
|
70
85
|
# https://tour.golang.org/basics/11
|
71
86
|
# https://golang.org/pkg/go/types/#pkg-variables
|
@@ -20,11 +20,47 @@ module GoaModelGen
|
|
20
20
|
@golang_helper ||= GolangHelper.new
|
21
21
|
end
|
22
22
|
|
23
|
+
def package(name = nil)
|
24
|
+
if name
|
25
|
+
@package = name
|
26
|
+
else
|
27
|
+
@package
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def dependencies
|
32
|
+
@dependencies ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear_dependencies
|
36
|
+
@dependencies = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def import(*packages)
|
40
|
+
packages.each do |package|
|
41
|
+
dependencies.push(package) unless dependencies.include?(package)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
GO_BASE_PATH = File.expand_path('../templates/base.go.erb', __FILE__)
|
46
|
+
|
47
|
+
PACKAGE_FOR_IMPORT = {
|
48
|
+
"datastore" => "google.golang.org/appengine/datastore",
|
49
|
+
}
|
50
|
+
|
23
51
|
def generate(template_path)
|
52
|
+
clear_dependencies
|
53
|
+
|
24
54
|
abs_path = File.expand_path('../' + template_path, __FILE__)
|
25
55
|
erb = ERB.new(File.read(abs_path), nil, "-")
|
26
56
|
erb.filename = abs_path
|
27
|
-
|
57
|
+
body = erb.result(binding).strip
|
58
|
+
|
59
|
+
raise "No package given in #{abs_path}" if package.blank?
|
60
|
+
|
61
|
+
base = ERB.new(File.read(GO_BASE_PATH), nil, "-")
|
62
|
+
base.filename = GO_BASE_PATH
|
63
|
+
base.result(binding).strip
|
28
64
|
end
|
29
65
|
|
30
66
|
def run(template_path, output_path, overwrite: false)
|
data/lib/goa_model_gen/loader.rb
CHANGED
@@ -2,6 +2,7 @@ require "goa_model_gen"
|
|
2
2
|
|
3
3
|
require "yaml"
|
4
4
|
|
5
|
+
require "goa_model_gen/logger"
|
5
6
|
require "goa_model_gen/type"
|
6
7
|
require "goa_model_gen/field"
|
7
8
|
require "goa_model_gen/source_file"
|
@@ -72,7 +73,7 @@ module GoaModelGen
|
|
72
73
|
def load(name)
|
73
74
|
d = lookup(name)
|
74
75
|
unless d
|
75
|
-
|
76
|
+
GoaModelGen.logger.info("#{name} not found in #{path}")
|
76
77
|
return nil
|
77
78
|
end
|
78
79
|
build_type(name, d)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "goa_model_gen"
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
module GoaModelGen
|
6
|
+
class << self
|
7
|
+
def logger
|
8
|
+
@logger ||= ::Logger.new($stderr)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Logger
|
13
|
+
class << self
|
14
|
+
def setup(log_level)
|
15
|
+
GoaModelGen.logger.level =
|
16
|
+
case log_level
|
17
|
+
when Integer then log_level
|
18
|
+
when String then ::Logger::SEV_LABEL.index(log_level.upcase)
|
19
|
+
else raise "Unsupported log_level: [#{log_level.class.name}] #{log_level.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,30 +2,11 @@
|
|
2
2
|
require 'goa_model_gen'
|
3
3
|
require 'goa_model_gen/type'
|
4
4
|
|
5
|
-
require "active_support/core_ext/string"
|
6
|
-
|
7
5
|
module GoaModelGen
|
8
6
|
class SourceFile
|
9
7
|
attr_reader :yaml_path, :types
|
10
8
|
def initialize(yaml_path, types)
|
11
9
|
@yaml_path, @types = yaml_path, types
|
12
10
|
end
|
13
|
-
|
14
|
-
def model_dependencies
|
15
|
-
@model_dependencies ||= calc_model_dependencies
|
16
|
-
end
|
17
|
-
|
18
|
-
def calc_model_dependencies
|
19
|
-
r = []
|
20
|
-
r << "github.com/goadesign/goa/uuid" if types.any?(&:use_uuid?)
|
21
|
-
if types.any?(&:store?)
|
22
|
-
r << "fmt"
|
23
|
-
r << "golang.org/x/net/context"
|
24
|
-
r << "google.golang.org/appengine/datastore"
|
25
|
-
r << "google.golang.org/appengine/log"
|
26
|
-
end
|
27
|
-
r << "time" if types.any?(&:has_time_field?)
|
28
|
-
r.uniq
|
29
|
-
end
|
30
11
|
end
|
31
12
|
end
|
@@ -7,15 +7,14 @@ def method_calling_exp(m, argument)
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
-%>
|
10
|
-
package controller
|
11
|
-
|
12
|
-
import (
|
13
|
-
"<%= config.go_package %>/app"
|
14
|
-
"<%= config.go_package %>/model"
|
15
|
-
)
|
10
|
+
<%- package 'controller' -%>
|
16
11
|
|
17
12
|
<%- source_file.types.select(&:gen_converter?).each do |type| -%>
|
18
13
|
<%- if type.payload -%>
|
14
|
+
<%-
|
15
|
+
import "#{config.go_package}/app"
|
16
|
+
import "#{config.go_package}/model"
|
17
|
+
-%>
|
19
18
|
func <%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %>) (*model.<%= type.name %>, error) {
|
20
19
|
model := &model.<%= type.name %>{}
|
21
20
|
if err := CopyFrom<%= type.name %>PayloadToModel(payload, model); err != nil {
|
@@ -34,7 +33,7 @@ func CopyFrom<%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %
|
|
34
33
|
|
35
34
|
<%-
|
36
35
|
type.fields_including_id.each do |f|
|
37
|
-
pf = type.payload.fields.detect{|pf|
|
36
|
+
pf = type.payload.fields.detect{|pf| pf.name == f.swagger_name }
|
38
37
|
if pf.nil?
|
39
38
|
-%>
|
40
39
|
// <%= f.name %> not found in payload fields
|
@@ -43,11 +42,11 @@ func CopyFrom<%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %
|
|
43
42
|
simple, with_error, method_name = f.payload_assignment_options(pf)
|
44
43
|
-%>
|
45
44
|
<%- if simple -%>
|
46
|
-
model.<%= f.name %> = payload.<%= f.
|
45
|
+
model.<%= f.name %> = payload.<%= f.goa_name %>
|
47
46
|
<%- elsif !with_error -%>
|
48
|
-
model.<%= f.name %> = <%= method_calling_exp(method_name, "payload.#{f.
|
47
|
+
model.<%= f.name %> = <%= method_calling_exp(method_name, "payload.#{f.goa_name}") %>
|
49
48
|
<%- else -%>
|
50
|
-
if v, err := <%= method_calling_exp(method_name, "payload.#{f.
|
49
|
+
if v, err := <%= method_calling_exp(method_name, "payload.#{f.goa_name}") %>; err != nil {
|
51
50
|
return err
|
52
51
|
} else {
|
53
52
|
model.<%= f.name %> = v
|
@@ -55,7 +54,7 @@ func CopyFrom<%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %
|
|
55
54
|
<%- end -%>
|
56
55
|
<%- end -%>
|
57
56
|
<%- end -%>
|
58
|
-
<%- type.payload.field_diffs(type.fields_including_id.map{|f| f.
|
57
|
+
<%- type.payload.field_diffs(type.fields_including_id.map{|f| f.swagger_name}).each do |pf| -%>
|
59
58
|
// No model field for payload field "<%= pf.name %>"
|
60
59
|
<%- end -%>
|
61
60
|
return nil
|
@@ -71,7 +70,7 @@ func <%= type.name %>ModelToMediaType(model *model.<%= type.name %>) (*app.<%= t
|
|
71
70
|
|
72
71
|
<%-
|
73
72
|
type.fields_including_id.each do |f|
|
74
|
-
mf = type.media_type.fields.detect{|mf| f.
|
73
|
+
mf = type.media_type.fields.detect{|mf| f.swagger_name == mf.name }
|
75
74
|
if mf.nil?
|
76
75
|
-%>
|
77
76
|
// <%= f.name %> not found for media type field
|
@@ -80,19 +79,19 @@ func <%= type.name %>ModelToMediaType(model *model.<%= type.name %>) (*app.<%= t
|
|
80
79
|
simple, with_error, method_name = f.media_type_assignment_options(mf)
|
81
80
|
-%>
|
82
81
|
<%- if simple -%>
|
83
|
-
r.<%=
|
82
|
+
r.<%= f.goa_name %> = model.<%= f.name %>
|
84
83
|
<%- elsif !with_error -%>
|
85
|
-
r.<%=
|
84
|
+
r.<%= f.goa_name %> = <%= method_calling_exp(method_name, "model.#{f.name}") %>
|
86
85
|
<%- else -%>
|
87
86
|
if val, err := <%= method_calling_exp(method_name, "model.#{f.name}") %>; err != nil {
|
88
87
|
return nil, err
|
89
88
|
} else {
|
90
|
-
r.<%=
|
89
|
+
r.<%= f.goa_name %> = val
|
91
90
|
}
|
92
91
|
<%- end
|
93
92
|
end -%>
|
94
93
|
<%- end -%>
|
95
|
-
<%- type.media_type.field_diffs(type.fields_including_id.map{|f| f.
|
94
|
+
<%- type.media_type.field_diffs(type.fields_including_id.map{|f| f.swagger_name}).each do |mf| -%>
|
96
95
|
// No model field for media type field "<%= mf.name %>"
|
97
96
|
<%- end -%>
|
98
97
|
return r, nil
|
@@ -1,11 +1,12 @@
|
|
1
|
-
package controller
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
)
|
1
|
+
<%- package 'controller' -%>
|
2
|
+
|
3
|
+
<%-
|
4
|
+
import(
|
5
|
+
"fmt",
|
6
|
+
"strconv",
|
7
|
+
"google.golang.org/appengine/datastore",
|
8
|
+
)
|
9
|
+
-%>
|
9
10
|
|
10
11
|
var NoModelGiven = fmt.Errorf("No model given")
|
11
12
|
var NoPayloadGiven = fmt.Errorf("No payload given")
|
@@ -1,10 +1,11 @@
|
|
1
|
-
package model
|
1
|
+
<%- package 'model' -%>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
)
|
3
|
+
<%-
|
4
|
+
import(
|
5
|
+
"golang.org/x/net/context",
|
6
|
+
"github.com/mjibson/goon",
|
7
|
+
)
|
8
|
+
-%>
|
8
9
|
|
9
10
|
// // Use the following code if you want to change kind name from model struct name.
|
10
11
|
// var ModelNameToKindMap = map[string]string{
|
@@ -1,22 +1,17 @@
|
|
1
|
-
package model
|
2
|
-
|
3
|
-
<%- unless source_file.model_dependencies.empty? -%>
|
4
|
-
import (
|
5
|
-
<%- golang_helper.partition(source_file.model_dependencies).each do |group| -%>
|
6
|
-
<%- group.each do |path| -%>
|
7
|
-
"<%= path %>"
|
8
|
-
<%- end -%>
|
9
|
-
|
10
|
-
<%- end -%>
|
11
|
-
)
|
12
|
-
<%- end -%>
|
1
|
+
<%- package "model" -%>
|
13
2
|
|
14
3
|
<%- source_file.types.each do |type| -%>
|
15
4
|
<%- if !type.fields.empty? -%>
|
5
|
+
<%-
|
6
|
+
type.field_type_packages.each do |pkg|
|
7
|
+
import(PACKAGE_FOR_IMPORT[pkg] || pkg)
|
8
|
+
end
|
9
|
+
-%>
|
16
10
|
type <%= type.name %> struct {
|
17
11
|
<%- if type.goon -%>
|
18
12
|
<%= type.id_definition %>
|
19
13
|
<%- if type.parent -%>
|
14
|
+
<%- import "google.golang.org/appengine/datastore" -%>
|
20
15
|
ParentKey *datastore.Key `datastore:"-" goon:"parent" json:"-"`
|
21
16
|
<%- end -%>
|
22
17
|
<%- end -%>
|
@@ -61,6 +56,7 @@ func (m *<%= model.name %>) PrepareToUpdate() error {
|
|
61
56
|
}
|
62
57
|
|
63
58
|
<%- if model.parent -%>
|
59
|
+
<%- import "context" -%>
|
64
60
|
func (m *<%= model.name %>) Parent(ctx context.Context) (*<%= model.parent %>, error) {
|
65
61
|
parentStore := &<%= model.parent %>Store{}
|
66
62
|
return parentStore.ByKey(ctx, m.ParentKey)
|
@@ -68,215 +64,3 @@ func (m *<%= model.name %>) Parent(ctx context.Context) (*<%= model.parent %>, e
|
|
68
64
|
<%- end -%>
|
69
65
|
|
70
66
|
<%- end -%>
|
71
|
-
|
72
|
-
<%- source_file.types.select(&:store?).each do |model| -%>
|
73
|
-
<%- store_name = "#{model.name}Store" -%>
|
74
|
-
type <%= store_name %> struct{
|
75
|
-
<%- if model.parent -%>
|
76
|
-
ParentKey *datastore.Key
|
77
|
-
<%- end -%>
|
78
|
-
}
|
79
|
-
|
80
|
-
func (s *<%= store_name %>) All(ctx context.Context) ([]*<%= model.name %>, error) {
|
81
|
-
return s.Select(ctx, s.Query(ctx))
|
82
|
-
}
|
83
|
-
|
84
|
-
func (s *<%= store_name %>) Select(ctx context.Context, q *datastore.Query) ([]*<%= model.name %>, error) {
|
85
|
-
g := GoonFromContext(ctx)
|
86
|
-
r := []*<%= model.name %>{}
|
87
|
-
log.Infof(ctx, "q is %v\n", q)
|
88
|
-
_, err := g.GetAll(q.EventualConsistency(), &r)
|
89
|
-
if err != nil {
|
90
|
-
log.Errorf(ctx, "Failed to Select <%= model.name %> because of %v\n", err)
|
91
|
-
return nil, err
|
92
|
-
}
|
93
|
-
return r, nil
|
94
|
-
}
|
95
|
-
|
96
|
-
func (s *<%= store_name %>) Query(ctx context.Context) *datastore.Query {
|
97
|
-
g := GoonFromContext(ctx)
|
98
|
-
k := g.Kind(new(<%= model.name %>))
|
99
|
-
// log.Infof(ctx, "Kind for <%= model.name %> is %v\n", k)
|
100
|
-
return datastore.NewQuery(k)
|
101
|
-
}
|
102
|
-
|
103
|
-
func (s *<%= store_name %>) ByID(ctx context.Context, <%= model.id_name_var %> <%= model.id_golang_type %>) (*<%= model.name %>, error) {
|
104
|
-
<%- if model.parent -%>
|
105
|
-
r := <%= model.name %>{ParentKey: s.ParentKey, <%= model.id_name %>: <%= model.id_name_var %>}
|
106
|
-
<%- else -%>
|
107
|
-
r := <%= model.name %>{<%= model.id_name %>: <%= model.id_name_var %>}
|
108
|
-
<%- end -%>
|
109
|
-
err := s.Get(ctx, &r)
|
110
|
-
if err != nil {
|
111
|
-
return nil, err
|
112
|
-
}
|
113
|
-
return &r, nil
|
114
|
-
}
|
115
|
-
|
116
|
-
func (s *<%= store_name %>) ByKey(ctx context.Context, key *datastore.Key) (*<%= model.name %>, error) {
|
117
|
-
if err := s.IsValidKey(ctx, key); err != nil {
|
118
|
-
log.Errorf(ctx, "<%= store_name %>.ByKey got Invalid key: %v because of %v\n", key, err)
|
119
|
-
return nil, err
|
120
|
-
}
|
121
|
-
|
122
|
-
<%- if model.parent -%>
|
123
|
-
r := <%= model.name %>{ParentKey: key.Parent(), <%= model.id_name %>: key.<%= model.key_id_method %>()}
|
124
|
-
<%- else -%>
|
125
|
-
r := <%= model.name %>{<%= model.id_name %>: key.<%= model.key_id_method %>()}
|
126
|
-
<%- end -%>
|
127
|
-
err := s.Get(ctx, &r)
|
128
|
-
if err != nil {
|
129
|
-
return nil, err
|
130
|
-
}
|
131
|
-
return &r, nil
|
132
|
-
}
|
133
|
-
|
134
|
-
func (s *<%= store_name %>) Get(ctx context.Context, m *<%= model.name %>) error {
|
135
|
-
g := GoonFromContext(ctx)
|
136
|
-
err := g.Get(m)
|
137
|
-
if err != nil {
|
138
|
-
log.Errorf(ctx, "Failed to Get <%= model.name %> because of %v\n", err)
|
139
|
-
return err
|
140
|
-
}
|
141
|
-
<%- if model.parent -%>
|
142
|
-
if err := s.ValidateParent(m); err != nil {
|
143
|
-
log.Errorf(ctx, "Invalid parent key for <%= model.name %> because of %v\n", err)
|
144
|
-
return err
|
145
|
-
}
|
146
|
-
<%- end -%>
|
147
|
-
|
148
|
-
return nil
|
149
|
-
}
|
150
|
-
|
151
|
-
func (s *<%= store_name %>) IsValidKey(ctx context.Context, key *datastore.Key) error {
|
152
|
-
if key == nil {
|
153
|
-
return fmt.Errorf("key is nil")
|
154
|
-
}
|
155
|
-
g := GoonFromContext(ctx)
|
156
|
-
expected := g.Kind(&<%= model.name %>{})
|
157
|
-
if key.Kind() != expected {
|
158
|
-
return fmt.Errorf("key kind must be %s but was %s", expected, key.Kind())
|
159
|
-
}
|
160
|
-
<%- if model.parent -%>
|
161
|
-
if key.Parent() == nil {
|
162
|
-
return fmt.Errorf("key parent must not be nil but was nil")
|
163
|
-
}
|
164
|
-
<%- end -%>
|
165
|
-
return nil
|
166
|
-
}
|
167
|
-
|
168
|
-
func (s *<%= store_name %>) Exist(ctx context.Context, m *<%= model.name %>) (bool, error) {
|
169
|
-
g := GoonFromContext(ctx)
|
170
|
-
key, err := g.KeyError(m)
|
171
|
-
if err != nil {
|
172
|
-
log.Errorf(ctx, "Failed to Get Key of %v because of %v\n", m, err)
|
173
|
-
return false, err
|
174
|
-
}
|
175
|
-
_, err = s.ByKey(ctx, key)
|
176
|
-
if err == datastore.ErrNoSuchEntity {
|
177
|
-
return false, nil
|
178
|
-
} else if err != nil {
|
179
|
-
log.Errorf(ctx, "Failed to get existance of %v because of %v\n", m, err)
|
180
|
-
return false, err
|
181
|
-
} else {
|
182
|
-
return true, nil
|
183
|
-
}
|
184
|
-
}
|
185
|
-
|
186
|
-
func (s *<%= store_name %>) Create(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
187
|
-
err := m.PrepareToCreate()
|
188
|
-
if err != nil {
|
189
|
-
return nil, err
|
190
|
-
}
|
191
|
-
if err := m.Validate(); err != nil {
|
192
|
-
return nil, err
|
193
|
-
}
|
194
|
-
|
195
|
-
<%- if model.goon['id_type'] == 'string' -%>
|
196
|
-
exist, err := s.Exist(ctx, m)
|
197
|
-
if err != nil {
|
198
|
-
return nil, err
|
199
|
-
}
|
200
|
-
if exist {
|
201
|
-
log.Errorf(ctx, "Failed to create %v because of another entity has same key\n", m)
|
202
|
-
return nil, fmt.Errorf("Duplicate <%= model.goon['id_name'] %> error: %q of %v\n", m.<%= model.goon['id_name'] %>, m)
|
203
|
-
}
|
204
|
-
<%- end -%>
|
205
|
-
|
206
|
-
return s.Put(ctx, m)
|
207
|
-
}
|
208
|
-
|
209
|
-
func (s *<%= store_name %>) Update(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
210
|
-
err := m.PrepareToUpdate()
|
211
|
-
if err != nil {
|
212
|
-
return nil, err
|
213
|
-
}
|
214
|
-
if err := m.Validate(); err != nil {
|
215
|
-
return nil, err
|
216
|
-
}
|
217
|
-
|
218
|
-
<%- if model.goon['id_type'] == 'string' -%>
|
219
|
-
exist, err := s.Exist(ctx, m)
|
220
|
-
if err != nil {
|
221
|
-
return nil, err
|
222
|
-
}
|
223
|
-
if !exist {
|
224
|
-
log.Errorf(ctx, "Failed to update %v because it doesn't exist\n", m)
|
225
|
-
return nil, fmt.Errorf("No data to update %q of %v\n", m.<%= model.goon['id_name'] %>, m)
|
226
|
-
}
|
227
|
-
<%- end -%>
|
228
|
-
|
229
|
-
return s.Put(ctx, m)
|
230
|
-
}
|
231
|
-
|
232
|
-
func (s *<%= store_name %>) Put(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
233
|
-
<%- if model.goon['id_type'] == 'UUID' -%>
|
234
|
-
if m.Id == "" {
|
235
|
-
m.Id = uuid.NewV4().String()
|
236
|
-
}
|
237
|
-
<%- end -%>
|
238
|
-
<%- if model.parent -%>
|
239
|
-
if err := s.ValidateParent(m); err != nil {
|
240
|
-
log.Errorf(ctx, "Invalid parent key for <%= model.name %> because of %v\n", err)
|
241
|
-
return nil, err
|
242
|
-
}
|
243
|
-
<%- end -%>
|
244
|
-
g := GoonFromContext(ctx)
|
245
|
-
key, err := g.Put(m)
|
246
|
-
if err != nil {
|
247
|
-
log.Errorf(ctx, "Failed to Put %v because of %v\n", m, err)
|
248
|
-
return nil, err
|
249
|
-
}
|
250
|
-
return key, nil
|
251
|
-
}
|
252
|
-
|
253
|
-
<%- if model.parent -%>
|
254
|
-
func (s *<%= store_name %>) ValidateParent(m *<%= model.name %>) error {
|
255
|
-
if s.ParentKey == nil {
|
256
|
-
return nil
|
257
|
-
}
|
258
|
-
if m.ParentKey == nil {
|
259
|
-
m.ParentKey = s.ParentKey
|
260
|
-
}
|
261
|
-
if !s.ParentKey.Equal(m.ParentKey) {
|
262
|
-
return fmt.Errorf("Invalid ParentKey for %v", m)
|
263
|
-
}
|
264
|
-
return nil
|
265
|
-
}
|
266
|
-
|
267
|
-
<%- end -%>
|
268
|
-
func (s *<%= store_name %>) Delete(ctx context.Context, m *<%= model.name %>) error {
|
269
|
-
g := GoonFromContext(ctx)
|
270
|
-
key, err := g.KeyError(m)
|
271
|
-
if err != nil {
|
272
|
-
log.Errorf(ctx, "Failed to Get key of %v because of %v\n", m, err)
|
273
|
-
return err
|
274
|
-
}
|
275
|
-
if err := g.Delete(key); err != nil {
|
276
|
-
log.Errorf(ctx, "Failed to Delete %v because of %v\n", m, err)
|
277
|
-
return err
|
278
|
-
}
|
279
|
-
return nil
|
280
|
-
}
|
281
|
-
|
282
|
-
<%- end -%>
|
@@ -0,0 +1,222 @@
|
|
1
|
+
<%- package "model" -%>
|
2
|
+
|
3
|
+
<%- source_file.types.select(&:store?).each do |model| -%>
|
4
|
+
<%- store_name = "#{model.name}Store" -%>
|
5
|
+
<%-
|
6
|
+
import(
|
7
|
+
"context",
|
8
|
+
"fmt",
|
9
|
+
"google.golang.org/appengine/datastore",
|
10
|
+
"google.golang.org/appengine/log",
|
11
|
+
)
|
12
|
+
-%>
|
13
|
+
type <%= store_name %> struct{
|
14
|
+
<%- if model.parent -%>
|
15
|
+
ParentKey *datastore.Key
|
16
|
+
<%- end -%>
|
17
|
+
}
|
18
|
+
|
19
|
+
func (s *<%= store_name %>) All(ctx context.Context) ([]*<%= model.name %>, error) {
|
20
|
+
return s.Select(ctx, s.Query(ctx))
|
21
|
+
}
|
22
|
+
|
23
|
+
func (s *<%= store_name %>) Select(ctx context.Context, q *datastore.Query) ([]*<%= model.name %>, error) {
|
24
|
+
g := GoonFromContext(ctx)
|
25
|
+
r := []*<%= model.name %>{}
|
26
|
+
log.Infof(ctx, "q is %v\n", q)
|
27
|
+
_, err := g.GetAll(q.EventualConsistency(), &r)
|
28
|
+
if err != nil {
|
29
|
+
log.Errorf(ctx, "Failed to Select <%= model.name %> because of %v\n", err)
|
30
|
+
return nil, err
|
31
|
+
}
|
32
|
+
return r, nil
|
33
|
+
}
|
34
|
+
|
35
|
+
func (s *<%= store_name %>) Query(ctx context.Context) *datastore.Query {
|
36
|
+
g := GoonFromContext(ctx)
|
37
|
+
k := g.Kind(new(<%= model.name %>))
|
38
|
+
// log.Infof(ctx, "Kind for <%= model.name %> is %v\n", k)
|
39
|
+
return datastore.NewQuery(k)
|
40
|
+
}
|
41
|
+
|
42
|
+
func (s *<%= store_name %>) ByID(ctx context.Context, <%= model.id_name_var %> <%= model.id_golang_type %>) (*<%= model.name %>, error) {
|
43
|
+
<%- if model.parent -%>
|
44
|
+
r := <%= model.name %>{ParentKey: s.ParentKey, <%= model.id_name %>: <%= model.id_name_var %>}
|
45
|
+
<%- else -%>
|
46
|
+
r := <%= model.name %>{<%= model.id_name %>: <%= model.id_name_var %>}
|
47
|
+
<%- end -%>
|
48
|
+
err := s.Get(ctx, &r)
|
49
|
+
if err != nil {
|
50
|
+
return nil, err
|
51
|
+
}
|
52
|
+
return &r, nil
|
53
|
+
}
|
54
|
+
|
55
|
+
func (s *<%= store_name %>) ByKey(ctx context.Context, key *datastore.Key) (*<%= model.name %>, error) {
|
56
|
+
if err := s.IsValidKey(ctx, key); err != nil {
|
57
|
+
log.Errorf(ctx, "<%= store_name %>.ByKey got Invalid key: %v because of %v\n", key, err)
|
58
|
+
return nil, err
|
59
|
+
}
|
60
|
+
|
61
|
+
<%- if model.parent -%>
|
62
|
+
r := <%= model.name %>{ParentKey: key.Parent(), <%= model.id_name %>: key.<%= model.key_id_method %>()}
|
63
|
+
<%- else -%>
|
64
|
+
r := <%= model.name %>{<%= model.id_name %>: key.<%= model.key_id_method %>()}
|
65
|
+
<%- end -%>
|
66
|
+
err := s.Get(ctx, &r)
|
67
|
+
if err != nil {
|
68
|
+
return nil, err
|
69
|
+
}
|
70
|
+
return &r, nil
|
71
|
+
}
|
72
|
+
|
73
|
+
func (s *<%= store_name %>) Get(ctx context.Context, m *<%= model.name %>) error {
|
74
|
+
g := GoonFromContext(ctx)
|
75
|
+
err := g.Get(m)
|
76
|
+
if err != nil {
|
77
|
+
log.Errorf(ctx, "Failed to Get <%= model.name %> because of %v\n", err)
|
78
|
+
return err
|
79
|
+
}
|
80
|
+
<%- if model.parent -%>
|
81
|
+
if err := s.ValidateParent(m); err != nil {
|
82
|
+
log.Errorf(ctx, "Invalid parent key for <%= model.name %> because of %v\n", err)
|
83
|
+
return err
|
84
|
+
}
|
85
|
+
<%- end -%>
|
86
|
+
|
87
|
+
return nil
|
88
|
+
}
|
89
|
+
|
90
|
+
func (s *<%= store_name %>) IsValidKey(ctx context.Context, key *datastore.Key) error {
|
91
|
+
if key == nil {
|
92
|
+
return fmt.Errorf("key is nil")
|
93
|
+
}
|
94
|
+
g := GoonFromContext(ctx)
|
95
|
+
expected := g.Kind(&<%= model.name %>{})
|
96
|
+
if key.Kind() != expected {
|
97
|
+
return fmt.Errorf("key kind must be %s but was %s", expected, key.Kind())
|
98
|
+
}
|
99
|
+
<%- if model.parent -%>
|
100
|
+
if key.Parent() == nil {
|
101
|
+
return fmt.Errorf("key parent must not be nil but was nil")
|
102
|
+
}
|
103
|
+
<%- end -%>
|
104
|
+
return nil
|
105
|
+
}
|
106
|
+
|
107
|
+
func (s *<%= store_name %>) Exist(ctx context.Context, m *<%= model.name %>) (bool, error) {
|
108
|
+
g := GoonFromContext(ctx)
|
109
|
+
key, err := g.KeyError(m)
|
110
|
+
if err != nil {
|
111
|
+
log.Errorf(ctx, "Failed to Get Key of %v because of %v\n", m, err)
|
112
|
+
return false, err
|
113
|
+
}
|
114
|
+
_, err = s.ByKey(ctx, key)
|
115
|
+
if err == datastore.ErrNoSuchEntity {
|
116
|
+
return false, nil
|
117
|
+
} else if err != nil {
|
118
|
+
log.Errorf(ctx, "Failed to get existance of %v because of %v\n", m, err)
|
119
|
+
return false, err
|
120
|
+
} else {
|
121
|
+
return true, nil
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
func (s *<%= store_name %>) Create(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
126
|
+
err := m.PrepareToCreate()
|
127
|
+
if err != nil {
|
128
|
+
return nil, err
|
129
|
+
}
|
130
|
+
if err := m.Validate(); err != nil {
|
131
|
+
return nil, err
|
132
|
+
}
|
133
|
+
|
134
|
+
<%- if model.goon['id_type'] == 'string' -%>
|
135
|
+
exist, err := s.Exist(ctx, m)
|
136
|
+
if err != nil {
|
137
|
+
return nil, err
|
138
|
+
}
|
139
|
+
if exist {
|
140
|
+
log.Errorf(ctx, "Failed to create %v because of another entity has same key\n", m)
|
141
|
+
return nil, fmt.Errorf("Duplicate <%= model.goon['id_name'] %> error: %q of %v\n", m.<%= model.goon['id_name'] %>, m)
|
142
|
+
}
|
143
|
+
<%- end -%>
|
144
|
+
|
145
|
+
return s.Put(ctx, m)
|
146
|
+
}
|
147
|
+
|
148
|
+
func (s *<%= store_name %>) Update(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
149
|
+
err := m.PrepareToUpdate()
|
150
|
+
if err != nil {
|
151
|
+
return nil, err
|
152
|
+
}
|
153
|
+
if err := m.Validate(); err != nil {
|
154
|
+
return nil, err
|
155
|
+
}
|
156
|
+
|
157
|
+
<%- if model.goon['id_type'] == 'string' -%>
|
158
|
+
exist, err := s.Exist(ctx, m)
|
159
|
+
if err != nil {
|
160
|
+
return nil, err
|
161
|
+
}
|
162
|
+
if !exist {
|
163
|
+
log.Errorf(ctx, "Failed to update %v because it doesn't exist\n", m)
|
164
|
+
return nil, fmt.Errorf("No data to update %q of %v\n", m.<%= model.goon['id_name'] %>, m)
|
165
|
+
}
|
166
|
+
<%- end -%>
|
167
|
+
|
168
|
+
return s.Put(ctx, m)
|
169
|
+
}
|
170
|
+
|
171
|
+
func (s *<%= store_name %>) Put(ctx context.Context, m *<%= model.name %>) (*datastore.Key, error) {
|
172
|
+
<%- if model.goon['id_type'] == 'UUID' -%>
|
173
|
+
<%- import "github.com/goadesign/goa/uuid" -%>
|
174
|
+
if m.Id == "" {
|
175
|
+
m.Id = uuid.NewV4().String()
|
176
|
+
}
|
177
|
+
<%- end -%>
|
178
|
+
<%- if model.parent -%>
|
179
|
+
if err := s.ValidateParent(m); err != nil {
|
180
|
+
log.Errorf(ctx, "Invalid parent key for <%= model.name %> because of %v\n", err)
|
181
|
+
return nil, err
|
182
|
+
}
|
183
|
+
<%- end -%>
|
184
|
+
g := GoonFromContext(ctx)
|
185
|
+
key, err := g.Put(m)
|
186
|
+
if err != nil {
|
187
|
+
log.Errorf(ctx, "Failed to Put %v because of %v\n", m, err)
|
188
|
+
return nil, err
|
189
|
+
}
|
190
|
+
return key, nil
|
191
|
+
}
|
192
|
+
|
193
|
+
<%- if model.parent -%>
|
194
|
+
func (s *<%= store_name %>) ValidateParent(m *<%= model.name %>) error {
|
195
|
+
if s.ParentKey == nil {
|
196
|
+
return nil
|
197
|
+
}
|
198
|
+
if m.ParentKey == nil {
|
199
|
+
m.ParentKey = s.ParentKey
|
200
|
+
}
|
201
|
+
if !s.ParentKey.Equal(m.ParentKey) {
|
202
|
+
return fmt.Errorf("Invalid ParentKey for %v", m)
|
203
|
+
}
|
204
|
+
return nil
|
205
|
+
}
|
206
|
+
|
207
|
+
<%- end -%>
|
208
|
+
func (s *<%= store_name %>) Delete(ctx context.Context, m *<%= model.name %>) error {
|
209
|
+
g := GoonFromContext(ctx)
|
210
|
+
key, err := g.KeyError(m)
|
211
|
+
if err != nil {
|
212
|
+
log.Errorf(ctx, "Failed to Get key of %v because of %v\n", m, err)
|
213
|
+
return err
|
214
|
+
}
|
215
|
+
if err := g.Delete(key); err != nil {
|
216
|
+
log.Errorf(ctx, "Failed to Delete %v because of %v\n", m, err)
|
217
|
+
return err
|
218
|
+
}
|
219
|
+
return nil
|
220
|
+
}
|
221
|
+
|
222
|
+
<%- end -%>
|
@@ -1,10 +1,7 @@
|
|
1
|
-
package model
|
2
|
-
|
3
|
-
import (
|
4
|
-
"gopkg.in/go-playground/validator.v9"
|
5
|
-
)
|
1
|
+
<%- package "model" -%>
|
6
2
|
|
7
3
|
<%- source_file.types.select(&:store?).each do |model| -%>
|
4
|
+
<%- import "gopkg.in/go-playground/validator.v9" -%>
|
8
5
|
func (m *<%= model.name %>) Validate() error {
|
9
6
|
validator := validator.New()
|
10
7
|
return validator.Struct(m)
|
data/lib/goa_model_gen/type.rb
CHANGED
@@ -25,6 +25,10 @@ module GoaModelGen
|
|
25
25
|
def has_time_field?
|
26
26
|
fields.any?{|f| f.type =~ TIME_TYPE_PATTERN}
|
27
27
|
end
|
28
|
+
|
29
|
+
def field_type_packages
|
30
|
+
fields.map(&:type_package).compact.uniq.sort
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
class Model < Type
|
@@ -93,7 +97,7 @@ module GoaModelGen
|
|
93
97
|
end
|
94
98
|
|
95
99
|
def assign_swagger_types(loader)
|
96
|
-
|
100
|
+
GoaModelGen.logger.debug "assign_swagger_types for #{name.inspect}"
|
97
101
|
# Original Type: VmDisk
|
98
102
|
# Swagger type : VmDisk
|
99
103
|
# Goa struct : VMDisk
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goa_model_gen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- akm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -122,11 +122,14 @@ files:
|
|
122
122
|
- lib/goa_model_gen/goa.rb
|
123
123
|
- lib/goa_model_gen/golang_helper.rb
|
124
124
|
- lib/goa_model_gen/loader.rb
|
125
|
+
- lib/goa_model_gen/logger.rb
|
125
126
|
- lib/goa_model_gen/source_file.rb
|
127
|
+
- lib/goa_model_gen/templates/base.go.erb
|
126
128
|
- lib/goa_model_gen/templates/converter.go.erb
|
127
129
|
- lib/goa_model_gen/templates/converter_base.go.erb
|
128
130
|
- lib/goa_model_gen/templates/goon.go.erb
|
129
131
|
- lib/goa_model_gen/templates/model.go.erb
|
132
|
+
- lib/goa_model_gen/templates/model_store.go.erb
|
130
133
|
- lib/goa_model_gen/templates/model_validation.go.erb
|
131
134
|
- lib/goa_model_gen/type.rb
|
132
135
|
- lib/goa_model_gen/version.rb
|
@@ -150,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
153
|
version: '0'
|
151
154
|
requirements: []
|
152
155
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.7.
|
156
|
+
rubygems_version: 2.7.6
|
154
157
|
signing_key:
|
155
158
|
specification_version: 4
|
156
159
|
summary: Generate model files for goa in golang
|