Skip to content

Commit

Permalink
Adding comments to functions
Browse files Browse the repository at this point in the history
  • Loading branch information
逍遥子(刘星宇) committed Sep 24, 2021
1 parent b3af27a commit aff0591
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 42 deletions.
35 changes: 35 additions & 0 deletions internal/common_fun.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2021 gotomicro
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package internal

import (
"unicode"
)

// UnderscoreName function mainly converts upper case to lower case and adds an underscore in between
func UnderscoreName(tableName string) string {
buf := []byte{}
for i, v := range tableName {
if unicode.IsUpper(v) {
if i != 0 {
buf = append(buf, '_')
}
buf = append(buf, byte(unicode.ToLower(v)))
} else {
buf = append(buf, byte(v))
}

}
return string(buf)
}
93 changes: 56 additions & 37 deletions model.go
Original file line number Diff line number Diff line change
@@ -1,69 +1,88 @@
// Copyright 2021 gotomicro
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package eql

import (
"reflect"
"strings"
"sync"

"github.com/gotomicro/eql/internal"
)

// TableMeta represents data model, or a table
type TableMeta struct {
tableName string
columns[] *ColumnMeta
// key 是字段名
fieldMap map[string]*ColumnMeta
typ reflect.Type
columns []*ColumnMeta
fieldMap map[string]*ColumnMeta
typ reflect.Type
}

// ColumnMeta represents model's field, or column
type ColumnMeta struct {
columnName string
fieldName string
typ reflect.Type
isPrimaryKey bool
columnName string
fieldName string
typ reflect.Type
isPrimaryKey bool
isAutoIncrement bool
}

type tableMetaOption func(meta *TableMeta)

// MetadaRegistry stores table metadata
type MetaRegistry interface {
// 这里传过来的 table 应该是结构体指针,例如 *User
Get(table interface{}) (*TableMeta, error)
Register(table interface{}, opts...tableMetaOption) (*TableMeta, error)
Register(table interface{}, opts ...tableMetaOption) (*TableMeta, error)
}

var defaultMetaRegistry = &tagMetaRegistry{}

// 我们的默认实现,它使用如下的规则
// 1. 结构体名字转表名,按照驼峰转下划线的方式
// 2. 字段名转列名,也是按照驼峰转下划线的方式
// tagMetaRegistry is the default implementation based on tag eql
type tagMetaRegistry struct {
metas map[reflect.Type]*TableMeta
metas sync.Map
}

// Get the metadata for each column of the data table,
// If there is none, it will register one and return the metadata for each column
func (t *tagMetaRegistry) Get(table interface{}) (*TableMeta, error) {
// 从 metas 里面去取,没有的话就调用 Register 新注册一个
panic("implement me")

if v, ok := t.metas.Load(reflect.TypeOf(table)); ok {
return v.(*TableMeta), nil
}
return t.Register(table)
}

// Register function generates a metadata for each column and places it in a thread-safe mapping to facilitate direct access to the metadata.
// And the metadata can be modified by user-defined methods opts
func (t *tagMetaRegistry) Register(table interface{}, opts ...tableMetaOption) (*TableMeta, error) {
// 拿到 table 的反射
// 遍历 table 的所有字段
// 对每一个字段检查 tag eql, 如果 eql 里面有 auto_increment, primary_key,就相应设置 ColumnMeta的值
// 最后处理所有的 opts
// 塞到 map 里面
panic("implement me")
}
rtype := reflect.TypeOf(table)
v := rtype.Elem()
columnMetas := []*ColumnMeta{}
lens := v.NumField()
fieldMap := make(map[string]*ColumnMeta, lens)
for i := 0; i < lens; i++ {
structField := v.Field(i)
tag := structField.Tag.Get("eql")
isAuto := strings.Contains(tag, "auto_increment")
isKey := strings.Contains(tag, "primary_key")
columnMeta := &ColumnMeta{
columnName: internal.UnderscoreName(structField.Name),
fieldName: structField.Name,
typ: structField.Type,
isAutoIncrement: isAuto,
isPrimaryKey: isKey,
}
columnMetas = append(columnMetas, columnMeta)
fieldMap[columnMeta.fieldName] = columnMeta
}
tableMeta := &TableMeta{
columns: columnMetas,
tableName: internal.UnderscoreName(v.Name()),
typ: rtype,
fieldMap: fieldMap,
}
for _, o := range opts {
o(tableMeta)
}
t.metas.Store(rtype, tableMeta)
return tableMeta, nil

}
25 changes: 20 additions & 5 deletions model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
package eql

import (
"github.com/stretchr/testify/assert"
"reflect"
"testing"

"github.com/stretchr/testify/assert"
)

func TestTagMetaRegistry(t *testing.T) {
Expand All @@ -26,7 +27,7 @@ func TestTagMetaRegistry(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, err)
assert.Nil(t, err)
assert.Equal(t, 4, len(meta.columns))
assert.Equal(t, 4, len(meta.fieldMap))
assert.Equal(t, reflect.TypeOf(tm), meta.typ)
Expand All @@ -36,8 +37,22 @@ func TestTagMetaRegistry(t *testing.T) {
assert.Equal(t, "id", idMeta.columnName)
assert.Equal(t, "Id", idMeta.fieldName)
assert.Equal(t, reflect.TypeOf(int64(0)), idMeta.typ)
assert.True(t, idMeta.isAutoIncrement)
assert.True(t, idMeta.isPrimaryKey)
assert.False(t, idMeta.isAutoIncrement)
assert.False(t, idMeta.isPrimaryKey)

idMetaFistName := meta.fieldMap["FistName"]
assert.Equal(t, "fist_name", idMetaFistName.columnName)
assert.Equal(t, "FistName", idMetaFistName.fieldName)
assert.Equal(t, reflect.TypeOf(string("")), idMetaFistName.typ)

idMetaLastName := meta.fieldMap["LastName"]
assert.Equal(t, "last_name", idMetaLastName.columnName)
assert.Equal(t, "LastName", idMetaLastName.fieldName)
assert.Equal(t, reflect.TypeOf(string("")), idMetaLastName.typ)

idMetaLastAge := meta.fieldMap["Age"]
assert.Equal(t, "age", idMetaLastAge.columnName)
assert.Equal(t, "Age", idMetaLastAge.fieldName)
assert.Equal(t, reflect.TypeOf(int8(0)), idMetaLastAge.typ)

// 把剩下的三个字段都断言一遍,注意它们的类型,而且它们也不是主键,也不是自增
}

0 comments on commit aff0591

Please sign in to comment.