generated from alecodes/base-template
222 lines
4.5 KiB
Go
222 lines
4.5 KiB
Go
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 main() {
|
|
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
|
|
}
|