3
0

Rename content to record on crm/types

This commit is contained in:
Mitja Zivkovic
2018-12-22 21:00:57 +01:00
committed by Denis Arh
parent 5584e6a2c9
commit fffcf7fa08
9 changed files with 131 additions and 131 deletions

View File

@@ -17,16 +17,16 @@ type (
ContentRepository interface {
With(ctx context.Context, db *factory.DB) ContentRepository
FindByID(id uint64) (*types.Content, error)
FindByID(id uint64) (*types.Record, error)
Report(moduleID uint64, params *types.ContentReport) (results interface{}, err error)
Report(moduleID uint64, params *types.RecordReport) (results interface{}, err error)
Find(moduleID uint64, query string, page int, perPage int, sort string) (*FindResponse, error)
Create(mod *types.Content) (*types.Content, error)
Update(mod *types.Content) (*types.Content, error)
Create(mod *types.Record) (*types.Record, error)
Update(mod *types.Record) (*types.Record, error)
DeleteByID(id uint64) error
Fields(mod *types.Content) ([]*types.ContentColumn, error)
Fields(mod *types.Record) ([]*types.RecordColumn, error)
}
FindResponseMeta struct {
@@ -39,7 +39,7 @@ type (
FindResponse struct {
Meta FindResponseMeta `json:"meta"`
Contents []*types.Content `json:"contents"`
Contents []*types.Record `json:"contents"`
}
content struct {
@@ -59,15 +59,15 @@ func (r *content) With(ctx context.Context, db *factory.DB) ContentRepository {
// @todo: update to accepted DeletedAt column semantics from SAM
func (r *content) FindByID(id uint64) (*types.Content, error) {
mod := &types.Content{}
func (r *content) FindByID(id uint64) (*types.Record, error) {
mod := &types.Record{}
if err := r.db().Get(mod, "SELECT * FROM crm_record WHERE id=? and deleted_at IS NULL", id); err != nil {
return nil, err
}
return mod, nil
}
func (r *content) Report(moduleID uint64, params *types.ContentReport) (results interface{}, err error) {
func (r *content) Report(moduleID uint64, params *types.RecordReport) (results interface{}, err error) {
crb := NewContentReportBuilder(moduleID, params)
var result = make([]map[string]interface{}, 0)
@@ -105,7 +105,7 @@ func (r *content) Find(moduleID uint64, query string, page int, perPage int, sor
Query: query,
Sort: sort,
},
Contents: make([]*types.Content, 0),
Contents: make([]*types.Record, 0),
}
query = "%" + query + "%"
@@ -215,27 +215,27 @@ func (r *content) Find(moduleID uint64, query string, page int, perPage int, sor
return response, nil
}
func (r *content) Create(mod *types.Content) (*types.Content, error) {
func (r *content) Create(mod *types.Record) (*types.Record, error) {
mod.ID = factory.Sonyflake.NextID()
mod.CreatedAt = time.Now()
mod.UserID = Identity(r.Context())
fields := make([]types.ContentColumn, 0)
fields := make([]types.RecordColumn, 0)
if err := json.Unmarshal(mod.Fields, &fields); err != nil {
return nil, errors.Wrap(err, "No content")
}
r.db().Exec("delete from crm_record_links where record_id=?", mod.ID)
for _, v := range fields {
v.ContentID = mod.ID
v.RecordID = mod.ID
if err := r.db().Replace("crm_record_column", v); err != nil {
return nil, errors.Wrap(err, "Error adding columns")
}
for _, related := range v.Related {
row := types.Related{
ContentID: v.ContentID,
Name: v.Name,
RelatedContentID: related,
RecordID: v.RecordID,
Name: v.Name,
RelatedRecordID: related,
}
if err := r.db().Replace("crm_record_links", row); err != nil {
return nil, errors.Wrap(err, "Error adding column links")
@@ -249,26 +249,26 @@ func (r *content) Create(mod *types.Content) (*types.Content, error) {
return mod, nil
}
func (r *content) Update(mod *types.Content) (*types.Content, error) {
func (r *content) Update(mod *types.Record) (*types.Record, error) {
now := time.Now()
mod.UpdatedAt = &now
fields := make([]types.ContentColumn, 0)
fields := make([]types.RecordColumn, 0)
if err := json.Unmarshal(mod.Fields, &fields); err != nil {
return nil, errors.Wrap(err, "Error when saving content, no content")
}
r.db().Exec("delete from crm_record_links where record_id=?", mod.ID)
for _, v := range fields {
v.ContentID = mod.ID
v.RecordID = mod.ID
if err := r.db().Replace("crm_record_column", v); err != nil {
return nil, errors.Wrap(err, "Error adding columns to database")
}
for _, related := range v.Related {
row := types.Related{
ContentID: v.ContentID,
Name: v.Name,
RelatedContentID: related,
RecordID: v.RecordID,
Name: v.Name,
RelatedRecordID: related,
}
if err := r.db().Replace("crm_record_links", row); err != nil {
return nil, errors.Wrap(err, "Error adding column links")
@@ -284,8 +284,8 @@ func (r *content) DeleteByID(id uint64) error {
return err
}
func (r *content) Fields(content *types.Content) ([]*types.ContentColumn, error) {
result := make([]*types.ContentColumn, 0)
func (r *content) Fields(content *types.Record) ([]*types.RecordColumn, error) {
result := make([]*types.RecordColumn, 0)
module := Module(r.ctx, r.db())
mod, err := module.FindByID(content.ModuleID)

View File

@@ -18,7 +18,7 @@ type (
jsonField string
moduleID uint64
params *types.ContentReport
params *types.RecordReport
}
)
@@ -26,7 +26,7 @@ var (
contentReportExprMatch = regexp.MustCompile(`^\s*(\w+)\((.+)\)\s*$`)
)
func NewContentReportBuilder(moduleID uint64, params *types.ContentReport) *contentReportBuilder {
func NewContentReportBuilder(moduleID uint64, params *types.RecordReport) *contentReportBuilder {
return &contentReportBuilder{
moduleID: moduleID,
params: params,

View File

@@ -26,16 +26,16 @@ type (
ContentService interface {
With(ctx context.Context) ContentService
FindByID(contentID uint64) (*types.Content, error)
FindByID(contentID uint64) (*types.Record, error)
Report(moduleID uint64, params *types.ContentReport) (interface{}, error)
Report(moduleID uint64, params *types.RecordReport) (interface{}, error)
Find(moduleID uint64, query string, page int, perPage int, sort string) (*repository.FindResponse, error)
Create(content *types.Content) (*types.Content, error)
Update(content *types.Content) (*types.Content, error)
Create(content *types.Record) (*types.Record, error)
Update(content *types.Record) (*types.Record, error)
DeleteByID(contentID uint64) error
Fields(mod *types.Content) ([]*types.ContentColumn, error)
Fields(mod *types.Record) ([]*types.RecordColumn, error)
}
)
@@ -56,7 +56,7 @@ func (s *content) With(ctx context.Context) ContentService {
}
}
func (s *content) FindByID(id uint64) (*types.Content, error) {
func (s *content) FindByID(id uint64) (*types.Record, error) {
response, err := s.repository.FindByID(id)
if err != nil {
return nil, err
@@ -64,7 +64,7 @@ func (s *content) FindByID(id uint64) (*types.Content, error) {
return response, s.preload(response, "page", "user", "fields")
}
func (s *content) Report(moduleID uint64, params *types.ContentReport) (interface{}, error) {
func (s *content) Report(moduleID uint64, params *types.RecordReport) (interface{}, error) {
return s.repository.Report(moduleID, params)
}
@@ -79,7 +79,7 @@ func (s *content) Find(moduleID uint64, query string, page int, perPage int, sor
return response, nil
}
func (s *content) Create(mod *types.Content) (*types.Content, error) {
func (s *content) Create(mod *types.Record) (*types.Record, error) {
response, err := s.repository.Create(mod)
if err != nil {
return nil, err
@@ -87,7 +87,7 @@ func (s *content) Create(mod *types.Content) (*types.Content, error) {
return response, s.preload(response, "user", "fields")
}
func (s *content) Update(content *types.Content) (c *types.Content, err error) {
func (s *content) Update(content *types.Record) (c *types.Record, err error) {
validate := func() error {
if content.ID == 0 {
return errors.New("Error updating content: invalid ID")
@@ -110,7 +110,7 @@ func (s *content) Update(content *types.Content) (c *types.Content, err error) {
})
}
func (s *content) Fields(mod *types.Content) ([]*types.ContentColumn, error) {
func (s *content) Fields(mod *types.Record) ([]*types.RecordColumn, error) {
return s.repository.Fields(mod)
}

View File

@@ -62,26 +62,26 @@ func TestContent(t *testing.T) {
assert(t, module.ID > 0, "Expected auto generated ID")
}
columns := []types.ContentColumn{
types.ContentColumn{
columns := []types.RecordColumn{
types.RecordColumn{
Name: "name",
Value: "Tit Petric",
},
types.ContentColumn{
types.RecordColumn{
Name: "email",
Value: "tit.petric@example.com",
},
types.ContentColumn{
types.RecordColumn{
Name: "options",
Related: []string{"1", "2", "3"},
},
types.ContentColumn{
types.RecordColumn{
Name: "description",
Value: "jack of all trades",
},
}
content1 := &types.Content{
content1 := &types.Record{
ModuleID: module.ID,
}
(&content1.Fields).Scan(func() []byte {
@@ -89,26 +89,26 @@ func TestContent(t *testing.T) {
return b
}())
columns2 := []types.ContentColumn{
types.ContentColumn{
columns2 := []types.RecordColumn{
types.RecordColumn{
Name: "name",
Value: "Marko Novak",
},
types.ContentColumn{
types.RecordColumn{
Name: "email",
Value: "marko.n@example.com",
},
types.ContentColumn{
types.RecordColumn{
Name: "options",
Related: []string{"1", "2", "3"},
},
types.ContentColumn{
types.RecordColumn{
Name: "description",
Value: "persona non grata",
},
}
content2 := &types.Content{
content2 := &types.Record{
ModuleID: module.ID,
}
(&content2.Fields).Scan(func() []byte {
@@ -156,7 +156,7 @@ func TestContent(t *testing.T) {
}
}
{
fields := make([]types.ContentColumn, 0)
fields := make([]types.RecordColumn, 0)
err := json.Unmarshal(ms.Fields, &fields)
assert(t, err == nil, "%+v", errors.Wrap(err, "Didn't expect error when unmarshalling"))
assert(t, len(fields) == len(columns), "Expected different field count: %d != %d", 2, len(fields))

View File

@@ -6,7 +6,7 @@ import (
"github.com/crusttech/crust/crm/types"
)
func (r *content) preloadAll(contents []*types.Content, fields ...string) error {
func (r *content) preloadAll(contents []*types.Record, fields ...string) error {
for _, content := range contents {
if err := r.preload(content, fields...); err != nil {
return err
@@ -15,7 +15,7 @@ func (r *content) preloadAll(contents []*types.Content, fields ...string) error
return nil
}
func (r *content) preload(content *types.Content, fields ...string) (err error) {
func (r *content) preload(content *types.Record, fields ...string) (err error) {
for _, field := range fields {
switch field {
case "fields":

View File

@@ -1,66 +0,0 @@
package types
import (
"regexp"
"strings"
)
type (
ContentReport struct {
Metrics []ContentReportMetric
Dimensions []ContentReportDimensions
}
ContentReportMetric struct {
Alias string
Expression string
}
ContentReportDimensions struct {
Alias string
Field string
Modifiers []string
}
)
var (
contentReportMetricScanRE *regexp.Regexp
contentReportDimensionScanRE *regexp.Regexp
)
func init() {
contentReportMetricScanRE = regexp.MustCompile("^(?:(\\w+):)?(.+)$")
contentReportDimensionScanRE = regexp.MustCompile("^(?:(\\w+):)?(\\w+)((?:\\|?\\w+)+)?$")
}
func (r *ContentReport) ScanMetrics(metrics ...string) {
r.Metrics = make([]ContentReportMetric, len(metrics))
for i := 0; i < len(metrics); i++ {
r.Metrics[i].Scan(metrics[i])
}
}
func (r *ContentReport) ScanDimensions(dimensions ...string) {
r.Dimensions = make([]ContentReportDimensions, len(dimensions))
for i := 0; i < len(dimensions); i++ {
r.Dimensions[i].Scan(dimensions[i])
}
}
func (m *ContentReportMetric) Scan(metric string) {
if match := contentReportMetricScanRE.FindStringSubmatch(metric); len(match) == 3 {
m.Alias = match[1]
m.Expression = match[2]
}
}
func (d *ContentReportDimensions) Scan(dimension string) {
if match := contentReportDimensionScanRE.FindStringSubmatch(dimension); len(match) == 4 {
d.Alias = match[1]
d.Field = match[2]
if len(match[3]) > 0 {
d.Modifiers = strings.Split(match[3][1:], "|")
}
}
}

66
crm/types/record_util.go Normal file
View File

@@ -0,0 +1,66 @@
package types
import (
"regexp"
"strings"
)
type (
RecordReport struct {
Metrics []RecordReportMetric
Dimensions []RecordReportDimensions
}
RecordReportMetric struct {
Alias string
Expression string
}
RecordReportDimensions struct {
Alias string
Field string
Modifiers []string
}
)
var (
recordReportMetricScanRE *regexp.Regexp
recordReportDimensionScanRE *regexp.Regexp
)
func init() {
recordReportMetricScanRE = regexp.MustCompile("^(?:(\\w+):)?(.+)$")
recordReportDimensionScanRE = regexp.MustCompile("^(?:(\\w+):)?(\\w+)((?:\\|?\\w+)+)?$")
}
func (r *RecordReport) ScanMetrics(metrics ...string) {
r.Metrics = make([]RecordReportMetric, len(metrics))
for i := 0; i < len(metrics); i++ {
r.Metrics[i].Scan(metrics[i])
}
}
func (r *RecordReport) ScanDimensions(dimensions ...string) {
r.Dimensions = make([]RecordReportDimensions, len(dimensions))
for i := 0; i < len(dimensions); i++ {
r.Dimensions[i].Scan(dimensions[i])
}
}
func (m *RecordReportMetric) Scan(metric string) {
if match := recordReportMetricScanRE.FindStringSubmatch(metric); len(match) == 3 {
m.Alias = match[1]
m.Expression = match[2]
}
}
func (d *RecordReportDimensions) Scan(dimension string) {
if match := recordReportDimensionScanRE.FindStringSubmatch(dimension); len(match) == 4 {
d.Alias = match[1]
d.Field = match[2]
if len(match[3]) > 0 {
d.Modifiers = strings.Split(match[3][1:], "|")
}
}
}

View File

@@ -4,8 +4,8 @@ import (
"testing"
)
func TestContentReport(t *testing.T) {
r := &ContentReport{}
func TestRecordReport(t *testing.T) {
r := &RecordReport{}
r.ScanMetrics("alias:exp")
if len(r.Metrics) == 0 {
t.Log("No metrics scanned")

View File

@@ -12,8 +12,8 @@ import (
)
type (
// Content is a stored row in the `record` table
Content struct {
// Record is a stored row in the `record` table
Record struct {
ID uint64 `json:"contentID,string" db:"id"`
ModuleID uint64 `json:"moduleID,string" db:"module_id"`
@@ -29,20 +29,20 @@ type (
DeletedAt *time.Time `db:"deleted_at" json:"deletedAt,omitempty"`
}
// ContentColumn is a stored row in the `record_column` table
ContentColumn struct {
ContentID uint64 `json:"-" db:"record_id"`
Name string `json:"name" db:"column_name"`
Value string `json:"value" db:"column_value"`
Related []string `json:"related" db:"-"`
// RecordColumn is a stored row in the `record_column` table
RecordColumn struct {
RecordID uint64 `json:"-" db:"record_id"`
Name string `json:"name" db:"column_name"`
Value string `json:"value" db:"column_value"`
Related []string `json:"related" db:"-"`
}
Related struct {
ContentID uint64 `json:"-" db:"record_id"`
Name string `json:"-" db:"column_name"`
RecordID uint64 `json:"-" db:"record_id"`
Name string `json:"-" db:"column_name"`
// RelatedContentID isn't necessarily a content ID (multiple-select anything goes options)
RelatedContentID string `json:"-" db:"rel_record_id"`
// RelatedRecordID isn't necessarily a record ID (multiple-select anything goes options)
RelatedRecordID string `json:"-" db:"rel_record_id"`
}
// Field - CRM input field definitions