package main import ( "database/sql" "encoding/csv" "encoding/json" "fmt" "io" "os" "path/filepath" "strings" synchronizator "git.alecodes.page/alecodes/synchronizator/pkg" _ "modernc.org/sqlite" ) type ProgrammingLanguage struct { Name string } func (language *ProgrammingLanguage) ToNode() (string, string, []byte, error) { metadata, err := json.Marshal("{\"test\": \"foo\"}") if err != nil { return "", "", nil, err } return "PROGRAMMING_LANGUAGE", language.Name, metadata, nil } func (language *ProgrammingLanguage) FromNode(_class string, name string, metadata []byte) error { if _class != "PROGRAMMING_LANGUAGE" { return fmt.Errorf("invalid class %s", _class) } language.Name = name return nil } type Library struct { Name string `json:"name"` Category string `json:"category"` Metadata map[string]interface{} `json:"metadata"` } func (library *Library) ToNode() (string, string, []byte, error) { metadata, err := json.Marshal(library.Metadata) if err != nil { return "", "", nil, err } return "LIBRARY", library.Name, metadata, nil } func (library *Library) FromNode(_class string, name string, metadata []byte) error { if _class != "LIBRARY" { return fmt.Errorf("invalid class %s", _class) } if err := json.Unmarshal(metadata, &library.Metadata); err != nil { return err } library.Name = name return nil } type ( BelognsTo struct{} IsSame struct{} ) func main2() { connection, err := sql.Open("sqlite", "db.sql") if err != nil { fmt.Println(err) return } defer connection.Close() opts := synchronizator.DefaultOptions // opts.Log_level = synchronizator.DEBUG opts.DANGEROUSLY_DROP_TABLES = true sync, err := synchronizator.New(connection, opts) if err != nil { fmt.Println(err) return } languages, err := loadData() if err != nil { fmt.Println(err) } for language, libraries := range languages { _, err := generateCollection( &ProgrammingLanguage{Name: strings.ToUpper(language)}, libraries, sync, ) if err != nil { println(err) } // fmt.Fprintf( // os.Stderr, // "libraries_collection%+v\n", // libraries_collection, // ) } golang, err := sync.GetNode(1) if err != nil { println(err) } fmt.Println("%v", golang) relationships, err := golang.GetOutRelations() if err != nil { panic(err) } for _, relationship := range relationships { fmt.Printf("%v -> %v -> %v\n", relationship.From, relationship.GetClass(), relationship.To) } } // generateCollection Main example of the usage of the synchronizator package func generateCollection( language *ProgrammingLanguage, libraries []Library, sync *synchronizator.DB, ) (*synchronizator.Collection, error) { language_libraries, err := sync.NewCollection(language) if err != nil { return nil, err } for _, library := range libraries { node, err := sync.NewNode(&library) if err != nil { return nil, err } data := &Library{} if err := node.Unmarshall(data); err != nil { println(err) } if err := language_libraries.AddChild(node); err != nil { return nil, err } } return language_libraries, nil } func loadData() (map[string][]Library, error) { // Find all CSV files files, err := filepath.Glob("examples/mock_data/*.csv") if err != nil { return nil, fmt.Errorf("failed to glob files: %w", err) } result := make(map[string][]Library) for _, file := range files { // Load CSV file libraries, err := processCSVFile(file) if err != nil { return nil, fmt.Errorf("failed to process %s: %w", file, err) } // Use base filename without extension as language_name language_name := filepath.Base(file) language_name = language_name[:len(language_name)-len(filepath.Ext(language_name))] result[language_name] = libraries } return result, nil } func processCSVFile(filename string) ([]Library, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() reader := csv.NewReader(file) // Skip header _, err = reader.Read() if err != nil { return nil, err } var libraries []Library // Read records for { record, err := reader.Read() if err == io.EOF { break } if err != nil { return nil, err } // Parse metadata JSON var metadata map[string]interface{} if err := json.Unmarshal([]byte(record[2]), &metadata); err != nil { return nil, fmt.Errorf("failed to parse metadata: %w", err) } library := Library{ Name: record[0], Category: record[1], Metadata: metadata, } libraries = append(libraries, library) } return libraries, nil }