Skip to content

Commit 48966d2

Browse files
authored
Merge pull request #34 from gcp-kit/issue/33
refで投入したデータを保存しておくようにする #33
2 parents 8a0fb5e + 1f3dd8d commit 48966d2

File tree

6 files changed

+125
-19
lines changed

6 files changed

+125
-19
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ gcloud auth application-default login
2828
gcloud config set ProjectID
2929
してる時に該当のプロジェクトに対して接続される感じ
3030

31+
### state_dir
32+
33+
投入したデータのステータスを保存するディレクトリ。
34+
空を指定した場合は、ステータスを保存しない。
35+
36+
作成されるファイル
37+
38+
```text
39+
state_dir/
40+
└── ref_ids.yaml # ref_idのリスト
41+
```
42+
3143
## テストデータの作り方
3244

3345
1. FirestoreのCollection名と同じディレクトリを作成する

cmd/fti/main.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ var (
2828
versionFlag = flag.Bool("v", false, "show version")
2929
)
3030

31+
const (
32+
refIDsFileName = "ref_ids.yaml"
33+
)
34+
3135
func main() {
3236
flag.Parse()
3337

@@ -60,11 +64,36 @@ func main() {
6064
log.Fatalf("failed to init firestore: %+v", err)
6165
}
6266

63-
is := inserter.NewInserter(client)
64-
err = is.Execute(context.Background(), &cfg)
67+
// refIDの一覧
68+
refIDs := inserter.RefIDs{}
69+
refFilePath := func() string {
70+
if cfg.StateDir != "" {
71+
return filepath.Join(cfg.StateDir, refIDsFileName)
72+
}
73+
return ""
74+
}()
75+
76+
// stateDirが指定されている場合は、そこからrefIDを読み込む
77+
if cfg.StateDir != "" {
78+
err := refIDs.LoadFromFile(refFilePath)
79+
if err != nil {
80+
log.Fatalf("failed to load state file: %+v", err)
81+
}
82+
}
83+
84+
is := inserter.NewInserter(client, refIDs)
85+
refIDs, err = is.Execute(context.Background(), &cfg)
6586
if err != nil {
6687
log.Fatalf("failed to execute insert: %+v", err)
6788
}
89+
90+
// stateDirが指定されている場合は、そこにrefIDを書き込む
91+
if cfg.StateDir != "" {
92+
err := refIDs.SaveToFile(refFilePath)
93+
if err != nil {
94+
log.Fatalf("failed to save state file: %+v", err)
95+
}
96+
}
6897
}
6998

7099
func initFirestore(ctx context.Context, cfg *config.Config) (*firestore.Client, error) {

pkg/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ type Config struct {
66
Targets []string `config:"targets,required" yaml:"targets"`
77
FirestoreProjectOnEmulator string `config:"firestore_project_on_emulator" yaml:"firestore_project_on_emulator"`
88
FirestoreEmulatorHost string `config:"firestore_emulator_host" yaml:"firestore_emulator_host"`
9+
StateDir string `config:"state_dir" yaml:"state_dir"`
910
}

pkg/inserter/common_inserter.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,26 @@ import (
1515
// CommonInserter - Inserterの共通部分
1616
type CommonInserter struct {
1717
client *firestore.Client
18-
refIDs map[string]string
18+
refIDs RefIDs
1919
}
2020

2121
// NewCommonInserter - CommonInserter constructor
22-
func NewCommonInserter(client *firestore.Client) *CommonInserter {
22+
func NewCommonInserter(client *firestore.Client, refIDs RefIDs) *CommonInserter {
23+
if refIDs == nil {
24+
refIDs = RefIDs{}
25+
}
26+
2327
return &CommonInserter{
2428
client: client,
25-
refIDs: map[string]string{},
29+
refIDs: refIDs,
2630
}
2731
}
2832

33+
// RefIDs - ref id の一覧を返す
34+
func (c *CommonInserter) RefIDs() map[string]string {
35+
return c.refIDs
36+
}
37+
2938
// CreateItem - item を Firestore に作る
3039
func (c *CommonInserter) CreateItem(ctx context.Context, cn, ID, refID string, item map[string]interface{}) error {
3140
item = c.tryParseDate(item)
@@ -93,7 +102,7 @@ func (c *CommonInserter) setRefs(item map[string]interface{}) map[string]interfa
93102
for k, v := range item {
94103
switch vt := v.(type) {
95104
case []interface{}:
96-
new := make([]string, len(vt))
105+
ni := make([]string, len(vt))
97106
isStr := true
98107
for i, vtv := range vt {
99108
vStr, ok := vtv.(string)
@@ -107,19 +116,19 @@ func (c *CommonInserter) setRefs(item map[string]interface{}) map[string]interfa
107116
if !ok {
108117
log.Printf("%s was not found", refID)
109118
} else {
110-
new[i] = rv
119+
ni[i] = rv
111120
}
112121
continue
113122
}
114123
n := c.replaceMultiRefs(vStr, reg)
115124
if n != "" {
116-
new[i] = n
125+
ni[i] = n
117126
continue
118127
}
119-
new[i] = vStr
128+
ni[i] = vStr
120129
}
121130
if isStr {
122-
item[k] = new
131+
item[k] = ni
123132
}
124133
case map[string]interface{}:
125134
for vtk, vtv := range vt {

pkg/inserter/inserter.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,41 @@ import (
1616

1717
// Inserter - Inserter
1818
type Inserter struct {
19+
commonInserter *CommonInserter
20+
1921
jsonInserter *JSONInserter
2022
yamlInserter *YAMLInserter
2123
jsInserter *JSInserter
2224
}
2325

2426
// NewInserter - Inserter constructor
25-
func NewInserter(client *firestore.Client) *Inserter {
26-
ci := NewCommonInserter(client)
27+
func NewInserter(client *firestore.Client, refIDs RefIDs) *Inserter {
28+
ci := NewCommonInserter(client, refIDs)
2729
return &Inserter{
28-
jsonInserter: NewJSONInserter(ci),
29-
jsInserter: NewJSInserter(ci),
30-
yamlInserter: NewYAMLInserter(ci),
30+
commonInserter: ci,
31+
jsonInserter: NewJSONInserter(ci),
32+
jsInserter: NewJSInserter(ci),
33+
yamlInserter: NewYAMLInserter(ci),
3134
}
3235
}
3336

3437
// Execute - ダミーデータソースの読み込みと実行処理呼び出しを行う
35-
func (i *Inserter) Execute(ctx context.Context, cfg *config.Config) error {
38+
func (i *Inserter) Execute(ctx context.Context, cfg *config.Config) (RefIDs, error) {
3639
targetDir := cfg.Targets
3740
for _, t := range targetDir {
3841
if !files.Exists(t) {
39-
return xerrors.Errorf("cannot find target directory: %s", targetDir)
42+
return nil, xerrors.Errorf("cannot find target directory: %s", targetDir)
4043
}
4144

4245
err := filepath.Walk(t, i.executeFile(ctx))
4346
if err != nil {
44-
return xerrors.Errorf("failed to execute file: %w", err)
47+
return nil, xerrors.Errorf("failed to execute file: %w", err)
4548
}
4649
}
4750

48-
return nil
51+
refIDs := i.commonInserter.RefIDs()
52+
53+
return refIDs, nil
4954
}
5055

5156
func (i *Inserter) executeFile(ctx context.Context) func(path string, info os.FileInfo, _ error) error {

pkg/inserter/ref_ids.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package inserter
2+
3+
import (
4+
"os"
5+
6+
"github.com/goccy/go-yaml"
7+
"golang.org/x/xerrors"
8+
)
9+
10+
// RefIDs - ref id の一覧
11+
type RefIDs map[string]string
12+
13+
// LoadFromFile - yamlファイルからrefIDを読み込む
14+
func (r RefIDs) LoadFromFile(path string) error {
15+
// pathのyamlファイル読み込む
16+
yb, err := os.ReadFile(path)
17+
if err != nil {
18+
return xerrors.Errorf("failed to read yaml file: %+v", err)
19+
}
20+
21+
// yamlファイルを構造体に変換する
22+
ym := new(RefIDs)
23+
err = yaml.Unmarshal(yb, ym)
24+
if err != nil {
25+
return xerrors.Errorf("failed to unmarshal yaml: %w", err)
26+
}
27+
// 構造体の値をrにコピーする
28+
for k, v := range *ym {
29+
r[k] = v
30+
}
31+
32+
return nil
33+
}
34+
35+
// SaveToFile - yamlファイルにrefIDを書き込む
36+
func (r RefIDs) SaveToFile(path string) error {
37+
// yamlに変換する
38+
yb, err := yaml.Marshal(r)
39+
if err != nil {
40+
return xerrors.Errorf("failed to marshal yaml: %w", err)
41+
}
42+
43+
// yamlファイルに書き込む
44+
err = os.WriteFile(path, yb, 0666)
45+
if err != nil {
46+
return xerrors.Errorf("failed to write yaml file: %w", err)
47+
}
48+
49+
return nil
50+
}

0 commit comments

Comments
 (0)