Skip to content
Snippets Groups Projects
database.go 3.29 KiB
Newer Older
  • Learn to ignore specific revisions
  • package database
    
    import (
    	"log"
    
    	"github.com/neo4j/neo4j-go-driver/neo4j"
    )
    
    //Database
    type Database struct {
    	driver  neo4j.Driver
    	session neo4j.Session
    }
    
    //NewDatabaseClient creates a database client
    func NewDatabaseClient(uri, username, password string, encrypted bool) Database {
    	//TODO: defer close()?
    	//		probably pretty nasty since it creates copies
    	driver := createDriver(uri, username, password, encrypted)
    	session := createSession(driver)
    
    	return Database{
    		driver:  driver,
    		session: session,
    	}
    
    }
    
    //createDriver creates a neo4j.Driver instance
    func createDriver(uri, username, password string, encrypted bool) neo4j.Driver {
    	driver, err := neo4j.NewDriver(
    		uri,
    		neo4j.BasicAuth(username, password, ""),
    		func(c *neo4j.Config) {
    			c.Encrypted = encrypted
    		},
    	)
    
    	logError("failed creating database Driver", err)
    
    	return driver
    }
    
    //createSession creates a neo4j.Session
    func createSession(driver neo4j.Driver) neo4j.Session {
    	sessionConfig := neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}
    	session, err := driver.NewSession(sessionConfig)
    
    	logError("failed creating database session", err)
    
    	return session
    }
    
    //StoreNodes stores the given nodes to the database
    func (d Database) StoreNodes(json string) {
    	session := d.session
    
    	query :=
    		`
    		WITH apoc.convert.fromJsonMap($stringToAdd)
    		AS value
    		UNWIND value.data as d
    		MERGE (device:Device {id: d.object_id})
    		ON CREATE SET device.nativeName = d.object_data.name[0].value,
    			device.deviceType = d.object_data.name[1].value,
    			device.serialNumber = d.object_data.name[2].value,
    			device.softwareVersion = d.object_data.name[3].value,
    			device.` + "`operational-state` = d.object_data.`operational-state`"
    
    	_, err := session.Run(
    		query, map[string]interface{}{
    			"stringToAdd": json,
    		})
    
    	logError("failed storing Nodes into database", err)
    
    	log.Printf("successfully added Nodes into database")
    }
    
    //StoreNodeEdgePoints stores the given node edge points (interfaces)
    func (d Database) StoreNodeEdgePoints(json string) {
    	session := d.session
    
    	queryEdgePoints :=
    		`
    		WITH apoc.convert.fromJsonMap($stringToAdd)
    		AS value
    		UNWIND value.data as i
    		MERGE (interface:Interface {id: i.object_id})
    		ON CREATE SET interface.object_type =i.object_type,
    		interface.localId = i.object_data.name[0].value,
    		interface.location = i.object_data.name[1].value,
    		interface.` + "`containing-node` = i.object_data.`containing-node`"
    
    	_, err := session.Run(
    		queryEdgePoints, map[string]interface{}{
    			"stringToAdd": json,
    		})
    
    	logError("failed storing NodeEdgePoints into database", err)
    
    	setNodeNodeEdgePointsRelation(session)
    
    	log.Printf("successfully added NodeEdgePoints into database")
    
    }
    
    //setNodeNodeEdgePointsRelation creates the database relations between "nodes" and "node edge points"
    func setNodeNodeEdgePointsRelation(session neo4j.Session) {
    	query :=
    		`
    		MATCH (d:Device), (i:Interface)
    		WHERE d.id = i.` + "`containing-node`" + `
    		CREATE (i)-[:BELONGS_TO]->(d)
    		`
    
    	_, err := session.Run(
    		query, map[string]interface{}{})
    
    	logError("failed storing NodeNodeEdgePointsRelation into database", err)
    
    	log.Printf("successfully stored NodeNodeEdgePointsRelation into database")
    }
    
    //logError logs error with custom and error message
    func logError(message string, err error) {
    	if err != nil {
    		log.Fatalf("%v: %v", message, err)
    	}
    }