[#2992] fixed zero-default value not being used if the field is not explicitly set when manually creating records

This commit is contained in:
Gani Georgiev
2023-07-25 20:35:29 +03:00
parent 34fe55686d
commit 1330e2e1e7
11 changed files with 6241 additions and 6054 deletions
+20 -4
View File
@@ -324,7 +324,7 @@ func (m *Record) Set(key string, value any) {
}
}
// Get returns a single record model data value for "key".
// Get returns a normalized single record model data value for "key".
func (m *Record) Get(key string) any {
switch key {
case schema.FieldNameId:
@@ -334,11 +334,27 @@ func (m *Record) Get(key string) any {
case schema.FieldNameUpdated:
return m.Updated
default:
if m.data == nil {
return nil
var v any
if m.data != nil {
v = m.data.Get(key)
}
return m.data.Get(key)
// normalize the field value in case it is missing or an incorrect type was set
// to ensure that the DB will always have normalized columns value.
if field := m.Collection().Schema.GetFieldByName(key); field != nil {
v = field.PrepareValue(v)
} else if m.collection.IsAuth() {
switch key {
case schema.FieldNameEmailVisibility, schema.FieldNameVerified:
v = cast.ToBool(v)
case schema.FieldNameLastResetSentAt, schema.FieldNameLastVerificationSentAt:
v, _ = types.ParseDateTime(v)
case schema.FieldNameUsername, schema.FieldNameEmail, schema.FieldNameTokenKey, schema.FieldNamePasswordHash:
v = cast.ToString(v)
}
}
return v
}
}
+40 -12
View File
@@ -729,6 +729,22 @@ func TestRecordSetAndGet(t *testing.T) {
Name: "field2",
Type: schema.FieldTypeNumber,
},
// fields that are not explicitly set to check
// the default retrieval value (single and multiple)
&schema.SchemaField{
Name: "field3",
Type: schema.FieldTypeBool,
},
&schema.SchemaField{
Name: "field4",
Type: schema.FieldTypeSelect,
Options: &schema.SelectOptions{MaxSelect: 2},
},
&schema.SchemaField{
Name: "field5",
Type: schema.FieldTypeRelation,
Options: &schema.RelationOptions{MaxSelect: types.Pointer(1)},
},
),
}
@@ -741,28 +757,40 @@ func TestRecordSetAndGet(t *testing.T) {
m.Set("unknown", 456) // undefined fields are allowed but not exported by default
m.Set("expand", map[string]any{"test": 123}) // should store the value in m.expand
if m.Get("id") != "test_id" {
t.Fatalf("Expected id %q, got %q", "test_id", m.Get("id"))
if v := m.Get("id"); v != "test_id" {
t.Fatalf("Expected id %q, got %q", "test_id", v)
}
if m.GetString("created") != "2022-09-15 00:00:00.123Z" {
t.Fatalf("Expected created %q, got %q", "2022-09-15 00:00:00.123Z", m.GetString("created"))
if v := m.GetString("created"); v != "2022-09-15 00:00:00.123Z" {
t.Fatalf("Expected created %q, got %q", "2022-09-15 00:00:00.123Z", v)
}
if m.GetString("updated") != "" {
t.Fatalf("Expected updated to be empty, got %q", m.GetString("updated"))
if v := m.GetString("updated"); v != "" {
t.Fatalf("Expected updated to be empty, got %q", v)
}
if m.Get("field1") != "123" {
t.Fatalf("Expected field1 %q, got %v", "123", m.Get("field1"))
if v, ok := m.Get("field1").(string); !ok || v != "123" {
t.Fatalf("Expected field1 %#v, got %#v", "123", m.Get("field1"))
}
if m.Get("field2") != 0.0 {
t.Fatalf("Expected field2 %v, got %v", 0.0, m.Get("field2"))
if v, ok := m.Get("field2").(float64); !ok || v != 0.0 {
t.Fatalf("Expected field2 %#v, got %#v", 0.0, m.Get("field2"))
}
if m.Get("unknown") != 456 {
t.Fatalf("Expected unknown %v, got %v", 456, m.Get("unknown"))
if v, ok := m.Get("field3").(bool); !ok || v != false {
t.Fatalf("Expected field3 %#v, got %#v", false, m.Get("field3"))
}
if v, ok := m.Get("field4").([]string); !ok || len(v) != 0 {
t.Fatalf("Expected field4 %#v, got %#v", "[]", m.Get("field4"))
}
if v, ok := m.Get("field5").(string); !ok || len(v) != 0 {
t.Fatalf("Expected field5 %#v, got %#v", "", m.Get("field5"))
}
if v := m.Get("unknown"); v != 456 {
t.Fatalf("Expected unknown %v, got %v", 456, v)
}
if m.Expand()["test"] != 123 {
+7 -3
View File
@@ -143,13 +143,17 @@ type SchemaField struct {
func (f *SchemaField) ColDefinition() string {
switch f.Type {
case FieldTypeNumber:
return "NUMERIC DEFAULT 0"
return "NUMERIC DEFAULT 0 NOT NULL"
case FieldTypeBool:
return "BOOLEAN DEFAULT FALSE"
return "BOOLEAN DEFAULT FALSE NOT NULL"
case FieldTypeJson:
return "JSON DEFAULT NULL"
default:
return "TEXT DEFAULT ''"
if opt, ok := f.Options.(MultiValuer); ok && opt.IsMultiple() {
return "JSON DEFAULT '[]' NOT NULL"
}
return "TEXT DEFAULT '' NOT NULL"
}
}
+27 -15
View File
@@ -63,47 +63,59 @@ func TestSchemaFieldColDefinition(t *testing.T) {
}{
{
schema.SchemaField{Type: schema.FieldTypeText, Name: "test"},
"TEXT DEFAULT ''",
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeNumber, Name: "test"},
"NUMERIC DEFAULT 0",
"NUMERIC DEFAULT 0 NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeBool, Name: "test"},
"BOOLEAN DEFAULT FALSE",
"BOOLEAN DEFAULT FALSE NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeEmail, Name: "test"},
"TEXT DEFAULT ''",
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeUrl, Name: "test"},
"TEXT DEFAULT ''",
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeEditor, Name: "test"},
"TEXT DEFAULT ''",
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeDate, Name: "test"},
"TEXT DEFAULT ''",
},
{
schema.SchemaField{Type: schema.FieldTypeSelect, Name: "test"},
"TEXT DEFAULT ''",
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeJson, Name: "test"},
"JSON DEFAULT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeFile, Name: "test"},
"TEXT DEFAULT ''",
schema.SchemaField{Type: schema.FieldTypeSelect, Name: "test"},
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeRelation, Name: "test"},
"TEXT DEFAULT ''",
schema.SchemaField{Type: schema.FieldTypeSelect, Name: "test_multiple", Options: &schema.SelectOptions{MaxSelect: 2}},
"JSON DEFAULT '[]' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeFile, Name: "test"},
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeFile, Name: "test_multiple", Options: &schema.FileOptions{MaxSelect: 2}},
"JSON DEFAULT '[]' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeRelation, Name: "test", Options: &schema.RelationOptions{MaxSelect: types.Pointer(1)}},
"TEXT DEFAULT '' NOT NULL",
},
{
schema.SchemaField{Type: schema.FieldTypeRelation, Name: "test_multiple", Options: &schema.RelationOptions{MaxSelect: nil}},
"JSON DEFAULT '[]' NOT NULL",
},
}