goa_model_gen 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|