Skip to content

Commit

Permalink
feat: static assets
Browse files Browse the repository at this point in the history
Image could be created at tmp directory. You have to give the permission to access the tmp directory. Use tmp-a. Access the generated pictures or any files via /static/file
  • Loading branch information
fdemir committed Jan 23, 2024
1 parent 04fdd06 commit 0da49f6
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 18 deletions.
1 change: 1 addition & 0 deletions example.hav
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
entity user {
name Person.Name
email Internet.Email
image Person.Image.Name
}

entity product {
Expand Down
9 changes: 9 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ func HandleBase(w http.ResponseWriter, r *http.Request, s *Source, opt *ServeOpt
return
}

if strings.HasPrefix(path, "static/") && opt.tmp {
mimeType := "application/octet-stream"

w.Header().Set("Content-Type", mimeType)

http.ServeFile(w, r, "/tmp/"+strings.TrimPrefix(path, "static/"))
return
}

if response == nil {
w.WriteHeader(http.StatusNotFound)
return
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type ServeOptions struct {
port string
queit bool
noCors bool
tmp bool
}

func read(path string) *Source {
Expand Down Expand Up @@ -98,12 +99,18 @@ func main() {
Usage: "disable CORS headers",
Aliases: []string{"nc"},
},
&cli.BoolFlag{
Name: "tmp-a",
Usage: "access to the tmp folder",
Aliases: []string{"tmp"},
},
},
Action: func(c *cli.Context) error {
host := c.String("host")
port := c.String("port")
quiet := c.Bool("quiet")
noCors := c.Bool("no-cors")
tmp := c.Bool("tmp-a")

file := c.Args().First()

Expand Down Expand Up @@ -138,6 +145,7 @@ func main() {
port: port,
queit: quiet,
noCors: noCors,
tmp: tmp,
}

serve(data, opt)
Expand Down
71 changes: 53 additions & 18 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import (
"io"
"reflect"
"strings"
"sync"
"text/scanner"
"unicode"

"github.com/jaswdr/faker"
)

const RECORD_COUNT = 10
const IMAGE_METHOD_KEY = "Person.Image.Name.Image.Name"

type Attribute struct {
Name string
Expand Down Expand Up @@ -95,39 +97,72 @@ func parseSource(src io.Reader) []Entity {
return entities
}

type entityResult struct {
EntityName string
Data *[]interface{}
}

// TODO: Map the all available funcitons instead of using reflection. Reflection is performance killer.
func generateFake(entities []Entity) map[string]*[]interface{} {
resultList := make(map[string]*[]interface{})

fake := faker.New()

methodCache := make(map[string]reflect.Value)
fakerValue := reflect.ValueOf(fake)

var wg sync.WaitGroup
resultsChan := make(chan entityResult, len(entities))

for _, entity := range entities {
lowercasedEntityName := strings.ToLower(entity.Name)
wg.Add(1)
go func(entity Entity) {
defer wg.Done()
lowercasedEntityName := strings.ToLower(entity.Name)
entityResults := make([]interface{}, 0, RECORD_COUNT)

for i := 0; i < RECORD_COUNT; i++ {
fakeValues := make(map[string]any)

for _, attr := range entity.Attributes {
methodKey := attr.Type
method, exists := methodCache[methodKey]

entityResults := make([]interface{}, 0, RECORD_COUNT)
resultList[lowercasedEntityName] = &entityResults
if !exists {
typeParts := strings.Split(attr.Type, ".")
method = fakerValue.MethodByName(typeParts[0])

for i := 0; i < RECORD_COUNT; i++ {
fakeValues := make(map[string]any)
for _, part := range typeParts[1:] {
method = method.Call([]reflect.Value{})[0].MethodByName(part)
methodKey += "." + part
}

for _, attr := range entity.Attributes {
methodKey := attr.Type
method, exists := methodCache[methodKey]
methodCache[methodKey] = method
}

if !exists {
typeParts := strings.Split(attr.Type, ".")
fakerMethod := fakerValue.MethodByName(typeParts[0])
method = fakerMethod.Call([]reflect.Value{})[0].MethodByName(typeParts[1])
methodCache[methodKey] = method
result := method.Call([]reflect.Value{})[0].Interface()

if methodKey == IMAGE_METHOD_KEY {
result = strings.Split(result.(string), "/")[2]
}

fakeValues[attr.Name] = result
}

fakeValues[attr.Name] = method.Call([]reflect.Value{})[0].Interface()
entityResults = append(entityResults, fakeValues)
}

*resultList[lowercasedEntityName] = append(*resultList[lowercasedEntityName], fakeValues)
}
resultsChan <- entityResult{EntityName: lowercasedEntityName, Data: &entityResults}
}(entity)
}

// Close the channel after all goroutines are done
go func() {
wg.Wait()
close(resultsChan)
}()

// Collect results
for result := range resultsChan {
resultList[result.EntityName] = result.Data
}

return resultList
Expand Down

0 comments on commit 0da49f6

Please sign in to comment.