-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
683 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,49 @@ | ||
package gofindit | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"strings" | ||
) | ||
|
||
type Document struct { | ||
Original any | ||
FieldValue map[string]any | ||
Original any | ||
FieldValues map[string]any | ||
FieldTypes map[string]string | ||
} | ||
|
||
func NewDocument(doc any) (*Document, error) { | ||
// Get field value map | ||
fieldValueMap, err := getFieldValueMap(doc) | ||
fieldValueMap, err := getFieldValues(doc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Get field types | ||
fieldTypes, err := getFieldTypes(doc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Create a new document | ||
document := Document{ | ||
Original: doc, | ||
FieldValue: fieldValueMap, | ||
Original: doc, | ||
FieldValues: fieldValueMap, | ||
FieldTypes: fieldTypes, | ||
} | ||
|
||
return &document, nil | ||
} | ||
|
||
func (d *Document) GetFieldValue(field string) (bool, any) { | ||
func (d *Document) GetFieldValue(field string) (any, string, bool) { | ||
// Check if the field exists | ||
_, ok := (*d).FieldValue[field] | ||
_, ok := (*d).FieldValues[field] | ||
if !ok { | ||
return false, nil | ||
} | ||
|
||
return true, (*d).FieldValue[field] | ||
} | ||
|
||
// Search returns a list of document IDs that match the given field and value | ||
func (d *Document) Search(documentQuery []DocumentQuery) (bool, error) { | ||
// Validate the document query | ||
for _, query := range documentQuery { | ||
err := query.Validate() | ||
if err != nil { | ||
return false, err | ||
} | ||
return nil, "", false | ||
} | ||
|
||
// Loop through the document query, get the value from the field | ||
// If any one of them does not match, return false | ||
// If all of them match, return true | ||
for _, query := range documentQuery { | ||
// Find the field | ||
found, value := d.GetFieldValue(query.Name) | ||
if !found { | ||
return false, fmt.Errorf("field %s not found in struct", query.Name) | ||
} | ||
|
||
// Get document value reflect type | ||
fieldType := reflect.ValueOf(d).FieldByName(query.Name) | ||
fmt.Println(fieldType) | ||
|
||
// Check if the value matches the query | ||
switch query.Type { | ||
case "match": | ||
// Compare values | ||
if value != query.Value { | ||
return false, fmt.Errorf("field %s does not match value %s", query.Name, query.Value) | ||
} | ||
case "partial": | ||
// Convert both values to string | ||
// and then do strings.Contains | ||
switch value.(type) { | ||
case string: | ||
if !strings.Contains(value.(string), query.Value.(string)) { | ||
return false, fmt.Errorf("field %s does not contain value %s", query.Name, query.Value) | ||
} | ||
default: | ||
return false, fmt.Errorf("field %s is not a string", query.Name) | ||
} | ||
case "range": | ||
// TODO: Implement range | ||
|
||
} | ||
} | ||
|
||
// Nothing failed so return true | ||
return true, nil | ||
} | ||
|
||
// DocumentQuery is a query to search fo | ||
type DocumentQuery struct { | ||
Name string | ||
Type string // "match", "partial", "range" | ||
Value any | ||
} | ||
|
||
func (dq *DocumentQuery) Validate() error { | ||
// Check if the name is not empty | ||
if dq.Name == "" { | ||
return fmt.Errorf("field name cannot be empty") | ||
} | ||
|
||
// Check if the type is empty | ||
if dq.Type == "" { | ||
dq.Type = "match" | ||
} | ||
|
||
// Check if the type is valid | ||
switch dq.Type { | ||
case "match": | ||
case "partial": | ||
case "range": | ||
default: | ||
return fmt.Errorf("invalid search type %s", (*dq).Type) | ||
// Get value type using reflect | ||
value, ok := (*d).FieldValues[field] | ||
if !ok { | ||
return nil, "", false | ||
} | ||
|
||
// Check if the value is valid | ||
// Get value type using reflect | ||
valueType := getBaseType(value) | ||
|
||
return nil | ||
return (*d).FieldValues[field], valueType, true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,54 @@ | ||
package gofindit | ||
|
||
import "fmt" | ||
|
||
func ExampleNewDocument() { | ||
type Test struct { | ||
Name string `find:"Name"` | ||
Age int `find:"Age"` | ||
} | ||
|
||
// Create a new document | ||
doc := Test{ | ||
Name: "Test", | ||
Age: 10, | ||
} | ||
|
||
// Create a new document | ||
document, err := NewDocument(doc) | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
fmt.Println(document.FieldTypes) | ||
fmt.Println(document.FieldValues) | ||
|
||
// Output: map[Age:int Name:string] | ||
// map[Age:10 Name:Test] | ||
} | ||
|
||
func ExampleDocument_GetFieldValue() { | ||
type Test struct { | ||
Name string `find:"name"` | ||
Age int `find:"age"` | ||
} | ||
|
||
// Create a new document | ||
doc := Test{ | ||
Name: "Test", | ||
Age: 10, | ||
} | ||
|
||
// Create a new document | ||
document, _ := NewDocument(doc) | ||
|
||
value, valueType, found := document.GetFieldValue("name") | ||
fmt.Println(value, valueType, found) | ||
|
||
value, valueType, found = document.GetFieldValue("age") | ||
fmt.Println(value, valueType, found) | ||
|
||
// Output: Test string true | ||
// 10 int true | ||
} |
Oops, something went wrong.