Пример #1
0
func UseTicket(tickets util.Ticket_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server Cyphering UseTicket\n")
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	cq := neoism.CypherQuery{
		Statement: `
		MATCH (t:Ticket)
		WHERE t.ID = {user_id} AND t.COUPON_ID = {id}
		SET t.VALID = "FALSE"
	`,
		Parameters: neoism.Props{"user_id": tickets.ID, "id": tickets.COUPON_ID},
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	return "Success", nil
}
func runServer(neoURL string, port int) {
	var err error
	db, err = neoism.Connect(neoURL)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("connected to %s\n", neoURL)
	neoutils.EnsureIndexes(db, map[string]string{
		"Thing": "uuid",
	})

	m := mux.NewRouter()
	http.Handle("/", m)

	m.HandleFunc("/content/{content_uuid}/annotations/annotated_by/{concept_uuid}", writeHandler).Methods("PUT")
	m.HandleFunc("/annotations/", allWriteHandler).Methods("PUT")
	cw = neocypherrunner.NewBatchCypherRunner(neoutils.StringerDb{db}, 1024)

	log.Printf("listening on %d", port)
	if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
		log.Printf("web stuff failed: %v\n", err)
	}

}
Пример #3
0
func connect() *neoism.Database {
	db, err := neoism.Connect("http://localhost:7474/db/data")
	if err != nil {
		log.Fatal(err)
	}
	return db
}
Пример #4
0
func connectDefault(neoURL string, conf *ConnectionConfig) (NeoConnection, error) {

	db, err := neoism.Connect(neoURL)
	if err != nil {
		return nil, err
	}

	if conf.HTTPClient != nil {
		db.Session.Client = conf.HTTPClient
	}

	exeName, err := osutil.Executable()
	if err == nil {
		_, exeFile := filepath.Split(exeName)
		db.Session.Header.Set("User-Agent", exeFile+" (using neoutils)")
	}

	var cr CypherRunner = db
	if conf.Transactional {
		cr = TransactionalCypherRunner{db}
	} else {
		cr = db
	}

	if conf.BatchSize > 0 {
		cr = NewBatchCypherRunner(cr, conf.BatchSize)
	}

	ie := &defaultIndexEnsurer{db}

	return &DefaultNeoConnection{neoURL, cr, ie, db}, nil
}
Пример #5
0
func UrlsIndexHandler(w http.ResponseWriter, req *http.Request) {
	neo, err := neoism.Connect(os.Getenv("GRAPHENEDB_URL"))

	if err != nil {
		printer.JSON(w, http.StatusServiceUnavailable, map[string]interface{}{
			"code":    http.StatusServiceUnavailable,
			"error":   http.StatusText(http.StatusServiceUnavailable),
			"message": err,
		})
	} else {
		urls := []Url{}
		cq := neoism.CypherQuery{
			Statement: `MATCH (url:Url) RETURN url`,
			Result:    &urls,
		}
		err := neo.Cypher(&cq)
		if err != nil {
			printer.JSON(w, http.StatusServiceUnavailable, map[string]interface{}{
				"code":    http.StatusServiceUnavailable,
				"error":   http.StatusText(http.StatusServiceUnavailable),
				"message": err,
			})
		}
		printer.JSON(w, http.StatusOK, map[string][]Url{"urls": urls})
	}
}
Пример #6
0
func getUserTickets(res *[]struct {
	A string `json:"n.COUPON_ID"`
}, id string) error {
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return err
	}

	cq := neoism.CypherQuery{
		Statement: `
			MATCH (n:Ticket)
			WHERE n.ID = {user_id}
			RETURN n.COUPON_ID
		`,
		Parameters: neoism.Props{"user_id": id},
		Result:     &res,
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return err
	}

	return nil
}
Пример #7
0
func RemoveCoupon(coupon util.GetCoupon_struct) (string, error){
	fmt.Printf("Accessing NEO4J Server Cyphering RemoveCoupon\n")
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")
	
	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err	
	}
	
	cq := neoism.CypherQuery{
    Statement: `
    	MATCH (n:Coupon)
      	WHERE n.ID = {user_id} AND n.COUPON_ID = {coupon_id} 
       	DELETE n
    `,
    Parameters: neoism.Props{"user_id": coupon.ID, "coupon_id": coupon.COUPON_ID},
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	return "Success", nil
}
Пример #8
0
func UpdateBusinessGeneral(update util.UpdateGeneralBusiness_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server: Cyphering UpdateBusinessGeneral\n")

	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	res := []struct {
		A string `json:"n.NAME"`
	}{}

	res2 := []struct {
		A string `json:"n.NAME"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
        	MATCH (n:Activity)
       		WHERE n.ID = {user_id}
			SET n.NAME = {name}, n.MIN_AGE = {min_age}, n.MAX_AGE = {max_age}, n.MIN_PEOPLE = {min_people},
									n.MAX_PEOPLE = {max_people}, n.MAIN_CATEGORY = {main_category}, n.SUB_CATEGORY = {sub_category}
        	RETURN n.NAME
    	`,
		Parameters: neoism.Props{"user_id": update.ID, "name": update.NAME, "min_age": update.MIN_AGE,
			"max_age": update.MAX_AGE, "min_people": update.MIN_PEOPLE, "max_people": update.MAX_PEOPLE,
			"main_category": update.MAIN_CATEGORY, "sub_category": update.SUB_CATEGORY},
		Result: &res,
	}

	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	cq = neoism.CypherQuery{
		Statement: `
        	MATCH (n:Coupon)
       		WHERE n.ID = {user_id}
        	SET	n.NAME = {name}
			RETURN n.NAME
    	`,
		Parameters: neoism.Props{"user_id": update.ID, "name": update.NAME},
		Result:     &res2,
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	if len(res) == 1 && len(res2) == 1 {
		return "Success", nil
	}

	return "Error: User Not Found", nil
}
Пример #9
0
func FindCoupon(id string) (bool, error) {
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return false, err
	}

	res := []struct {
		A string `json:"n.ID"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
        	MATCH (n:Coupon)
       		WHERE n.COUPON_ID = {id}
        	RETURN n.ID
    	`,
		Parameters: neoism.Props{"id": id},
		Result:     &res,
	}

	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return false, err
	}

	if len(res) == 0 {
		return false, nil
	}

	return true, nil
}
Пример #10
0
func LoginBusiness(login Util.Login_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server Cyphering BusinessLogin\n")
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	res := []struct {
		A string `json:"n.USER_ID"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
        	MATCH (n:Business)
       		WHERE n.USER_ID = {user_id} AND n.PASSWORD = {password}
        	RETURN n.USER_ID
    	`,
		Parameters: neoism.Props{"user_id": login.ID, "password": login.PASSWORD},
		Result:     &res,
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	if len(res) == 1 {
		return "Success", nil
	}

	fmt.Printf("Business User Login Failed\n")
	return "Failed", nil
}
Пример #11
0
Файл: neo.go Проект: vly/ssdir
func (db *Database) Connect(hostname string) (database *neoism.Database, ok int) {
	database, err := neoism.Connect("http://127.0.0.1:7474/db/data")
	if err != nil {
		log.Fatal(err)
	}
	db.db = database
	return
}
Пример #12
0
func init() {
	resetDB()
	var err error
	db, err = neoism.Connect("http://localhost:7474/db/data")
	if err != nil {
		panic(err)
	}
}
Пример #13
0
func GetActiveCoupons(coupon util.GetCoupon_struct) (string, error){
	fmt.Printf("Accessing NEO4J Server Cyphering GetActiveCoupon\n")
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")
	
	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err	
	}
	
	res := []struct {
		N neoism.Node 
    }{}

	cq := neoism.CypherQuery{
    Statement: `
    	MATCH (n:Coupon)
      	WHERE n.ID = {user_id} AND n.VALID = "TRUE"
       	RETURN n
    `,
    Parameters: neoism.Props{"user_id": coupon.ID},
    Result:     &res,
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	response := ""
	data := map[string]interface{}{}
	if len(res) != 0 {
		jsonString := "{\"coupons\": ["
		for i:=0; i < len(res); i++ {
			coupon, err := json.Marshal(res[i].N.Data)
			if err != nil {
				fmt.Printf("%s\n", err)
			}	
			jsonString += string(coupon)
			if i != (len(res)-1){
				jsonString += ","
			}
		}
		jsonString += "]}"

		dec := json.NewDecoder(strings.NewReader(jsonString))
		dec.Decode(&data)
		
		coupons, err := json.Marshal(data)
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		response = string(coupons)
			
		return response, nil
	}

	return "No Active Coupons", nil
}
Пример #14
0
func UpdateBusinessAddress(update util.UpdateAddressBusiness_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server: Cyphering UpdateBusinessAddress\n")

	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	res := []struct {
		A string `json:"n.NAME"`
	}{}

	res2 := []struct {
		A string `json:"n.NAME"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
        	MATCH (n:Activity)
       		WHERE n.ID = {user_id}
        	SET n.ADDRESS = {address}, n.TOWNSHIP = {township}, n.CAMPUS = {campus}
			RETURN n.NAME
    	`,
		Parameters: neoism.Props{"user_id": update.ID, "address": update.ADDRESS, "township": update.TOWNSHIP, "campus": update.CAMPUS},
		Result:     &res,
	}

	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	cq = neoism.CypherQuery{
		Statement: `
        	MATCH (n:Coupon)
       		WHERE n.ID = {user_id}
        	SET n.ADDRESS = {address}, n.CAMPUS = {campus}
			RETURN n.NAME
    	`,
		Parameters: neoism.Props{"user_id": update.ID, "address": update.ADDRESS, "campus": update.CAMPUS},
		Result:     &res2,
	}

	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	if len(res) == 1 && len(res2) == 1 {
		return "Success", nil
	}

	return "Error: User Not Found", nil
}
Пример #15
0
func main() {
	neo, err := neoism.Connect(os.Getenv("GRAPHENEDB_URL"))
	if err != nil {
		fmt.Println(err)
		return
	}

	createUrls(neo)
}
Пример #16
0
// Constructor, use this when creating a new Query struct.
func NewQuery(uri string) *Query {
	neo4jdb, err := neoism.Connect(uri)
	panicIfErr(err)

	query := Query{neo4jdb}
	query.DatabaseInit()

	return &query
}
Пример #17
0
func Cleanup() {
	db, _ := neoism.Connect("http://*****:*****@localhost:7474")
	cq := neoism.CypherQuery{
		Statement: `MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r`,
	}
	if err := db.Cypher(&cq); err != nil {
		panic(err)
	}
}
Пример #18
0
func connect(app *App) {
	url := app.Config.Neo4JUrl
	var db *neoism.Database
	db, err := neoism.Connect(url)
	if err != nil {
		log.Fatal("Could not connect to DB", err)
	}
	app.GraphDB = db
}
Пример #19
0
func main() {
	flag.Parse()

	numCpus := runtime.NumCPU()
	prevProcs := runtime.GOMAXPROCS(*threads)
	glog.WithField("num_cpu", numCpus).
		WithField("threads", *threads).
		WithField("prev_maxprocs", prevProcs).
		Info("Set max procs to threads")

	if len(*rdfGzips) == 0 {
		glog.Fatal("No RDF GZIP files specified")
	}

	db, err := neoism.Connect("http://localhost:7474/db/data")
	if err != nil {
		log.Fatal(err)
	}

	files := strings.Split(*rdfGzips, ",")
	for _, path := range files {
		if len(path) == 0 {
			continue
		}
		glog.WithField("path", path).Info("Handling...")
		f, err := os.Open(path)
		if err != nil {
			glog.WithError(err).Fatal("Unable to open rdf file.")
		}

		r, err := gzip.NewReader(f)
		if err != nil {
			glog.WithError(err).Fatal("Unable to create gzip reader.")
		}

		count, err := HandleRdfReader(db, r, *mod)
		if err != nil {
			glog.WithError(err).Fatal("While handling rdf reader.")
		}
		glog.WithField("count", count).Info("RDFs parsed")

		r.Close()
		f.Close()
	}

	p := neoism.Props{"_xid_": 10}
	n, created, err := db.GetOrCreateNode("Entity", "_xid_", p)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Created", created)
	p, err = n.Properties()
	fmt.Println(n.Id(), p, err)
}
Пример #20
0
func initdb() {
	//neoism.Connect("http://*****:*****@server:port")
	var err error
	db, err = neoism.Connect("http://*****:*****@carsimulator.sb05.stations.graphenedb.com:24789")
	//If error connecting to database, halt execution and display error message
	if err != nil {
		panic(err)
	}
	if db == nil {
		panic("Database object is null")
	}
}
Пример #21
0
func UpdateUserStudent(update util.Student_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server: Cyphering UpdateUserStudent\n")

	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	res := []struct {
		A string `json:"n.RUID"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
		 	MATCH (n:Student)
			WHERE n.USER_ID = {user_id}
			SET n.RUID = {ruid}, n.DEGREE = {degree}, n.CAMPUS = {campus}, n.YEAR = {year}
		 	RETURN n.ruid
		`,
		Parameters: neoism.Props{"user_id": update.ID, "ruid": update.RUID, "degree": update.DEGREE,
			"campus": update.CAMPUS, "year": update.YEAR},
		Result: &res,
	}

	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	if len(res) == 1 {
		return "Success", nil
	} else {
		cq := neoism.CypherQuery{
			Statement: `
		 	CREATE (n:Student {USER_ID: {user_id}, RUID: {ruid}, DEGREE: {degree}, CAMPUS: {campus}, YEAR: {year}})
		`,
			Parameters: neoism.Props{"user_id": update.ID, "ruid": update.RUID, "degree": update.DEGREE,
				"campus": update.CAMPUS, "year": update.YEAR},
			Result: &res,
		}

		err = database.Cypher(&cq)
		if err != nil {
			fmt.Printf("Error Cyphering To Database\n")
			return "Internal Service Error", err
		}

		return "Success", nil
	}
}
Пример #22
0
func (m *TaxonomyEngine) Start() {

	db, err := neoism.Connect("http://*****:*****@localhost:7474/db/data/")
	if err != nil {
		fmt.Println("error in setup, db is:", db)
		panic(err)
	}

	m.db = db

	m.cache.Setup()
}
Пример #23
0
func CreateNewConnection(specialLabel ...string) Connection {
	log.Println("Trying to connect database...")
	//http://your_user:[email protected]/db/data/
	//	dbpath := "http://*****:*****@localhost:7474/db/data"
	dbpath := "http://*****:*****@localhost:7474/db/data"
	db, err := neoism.Connect(dbpath)
	utils.HandleError(err)

	c := NewConnectionNeo(dbpath, db, specialLabel...)
	return Connection(&c)

}
Пример #24
0
func main() {

	neoUrl := os.Getenv("NEO_URL")
	if neoUrl == "" {
		log.Println("no $NEO_URL set, defaulting to local")
		neoUrl = "http://localhost:7474/db/data"
	}
	log.Printf("connecting to %s\n", neoUrl)

	var err error
	db, err = neoism.Connect(neoUrl)
	if err != nil {
		panic(err)
	}

	ensureIndexes(db)

	writeQueue = make(chan organisation, 2048)

	port := 8080

	m := mux.NewRouter()
	http.Handle("/", m)

	m.HandleFunc("/organisations/{uuid}", idWriteHandler).Methods("PUT")
	m.HandleFunc("/organisations/", allWriteHandler).Methods("PUT")

	go func() {
		log.Printf("listening on %d", port)
		if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
			log.Printf("web stuff failed: %v\n", err)
		}
	}()

	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		orgWriteLoop()
		wg.Done()
	}()

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	// wait for ctrl-c
	<-c
	close(writeQueue)
	wg.Wait()
	println("exiting")

}
Пример #25
0
func CreateTicket(tickets util.Ticket_struct) (string, error) {
	fmt.Printf("Accessing NEO4J Server Cyphering CreateTicket\n")
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "Internal Service Error", err
	}

	res := []struct {
		A string `json:"n.ID"`
	}{}

	cq := neoism.CypherQuery{
		Statement: `
    	MATCH (n:Ticket)
      	WHERE n.ID = {user_id} AND n.VALID = "TRUE"
       	RETURN n.ID
    `,
		Parameters: neoism.Props{"user_id": tickets.ID},
		Result:     &res,
	}
	err = database.Cypher(&cq)
	if err != nil {
		fmt.Printf("Error Cyphering To Database\n")
		return "Internal Service Error", err
	}

	if len(res) < 3 {
		cq = neoism.CypherQuery{
			Statement: `
			CREATE (n:Ticket {ID: {user_id},
						COUPON_ID: {id},
						VALID: "TRUE"
				})
		`,
			Parameters: neoism.Props{"user_id": tickets.ID,
				"id": tickets.COUPON_ID},
		}

		err = database.Cypher(&cq)
		if err != nil {
			fmt.Printf("Error Cyphering To Database\n")
			return "Internal Service Error", err
		}

		return "Success", nil
	} else {
		fmt.Printf("User Reached Max Tickets\n")
		return "Max Active Tickets Reached", nil
	}
}
Пример #26
0
// GetGraph returns a connected neoism.Database
func GetGraph() *neoism.Database {
	dsn := os.Getenv("IN_COMMON_NEO4J_DSN")
	if dsn == "" {
		dsn = "http://*****:*****@localhost:7474/db/data"
	}

	db, err := neoism.Connect(dsn)
	if err != nil {
		panic(err)
	}

	return db
}
Пример #27
0
func initdb() {
	var err error

	//neoism.Connect("http://*****:*****@server:port")
	panic("This script works on the default example films and actors database, you will need that running on localhost. Put your password in the Connect statement below then comment out this panic line. The default user is neo4j")

	db, err = neoism.Connect("http://*****:*****@localhost:7474/")
	if err != nil {
		panic(err)
	}
	if db == nil {
		panic("Database object is null")
	}
}
Пример #28
0
func getCouponsFromMatchs(business []struct {
	A string `json:"n.ID"`
}) (string, int, error) {
	database, err := neoism.Connect("http://*****:*****@localhost:7474/db/data")

	if err != nil {
		fmt.Printf("NEO4J Connection FAILED\n")
		return "", 0, err
	}

	coupon := []struct {
		A string `json:"n.COUPON_ID"`
	}{}

	size := 0
	coupons := ""
	for i := 0; i < len(business); i++ {
		id := business[i].A

		cq := neoism.CypherQuery{
			Statement: `
			MATCH (n:Coupon)
			WHERE n.ID = {user_id} AND n.VALID = "TRUE"
			RETURN n.COUPON_ID
		`,
			Parameters: neoism.Props{"user_id": id},
			Result:     &coupon,
		}
		err = database.Cypher(&cq)
		if err != nil {
			fmt.Printf("Error Cyphering To Database\n")
			return "", 0, err
		}

		if i > 0 && len(coupon) != 0 {
			coupons += ","
		}

		for x := 0; x < len(coupon); x++ {
			size++
			coupons += coupon[x].A
			if x != (len(coupon) - 1) {
				coupons += ","
			}
		}
	}

	return coupons, size, nil
}
Пример #29
0
// creates a new driver with the unique set of config options specified in the config file
func newDriver(c *backend.Config) (backend.Graph, error) {

	url := fmt.Sprintf(
		"http://%s:%s@%s:%d",
		c.StringKey("user"),
		c.StringKey("password"),
		c.StringKey("host"),
		c.IntKey("port"),
	)

	//	db, err := sql.Open("neo4j-cypher", url)
	db, err := neoism.Connect(url)
	return &Driver{
		Connection: db,
	}, err
}
Пример #30
0
func main() {
	var err error
	db, err = neoism.Connect(os.Getenv("NEO4J_URL"))
	if err != nil {
		log.Fatal(err)
	}

	// middleware
	middle := interpose.New()
	middle.Use(adaptors.FromNegroni(cors.New(cors.Options{
		// CORS
		AllowedOrigins: []string{"*"},
	})))

	// router
	router := mux.NewRouter()
	router.StrictSlash(true) // redirects '/path' to '/path/'
	middle.UseHandler(router)
	// ~

	// > routes
	router.HandleFunc("/rel/", func(w http.ResponseWriter, r *http.Request) {
		handlers.CreateRelationship(db, w, r)
	}).Methods("POST")
	router.HandleFunc("/eql/", func(w http.ResponseWriter, r *http.Request) {
		handlers.CreateEquality(db, w, r)
	}).Methods("POST")
	router.HandleFunc("/btw/", func(w http.ResponseWriter, r *http.Request) {
		handlers.RelationshipsBetween(db, w, r)
	}).Methods("GET")
	router.HandleFunc("/cluster.svg", func(w http.ResponseWriter, r *http.Request) {
		handlers.ViewRelationships(db, w, r)
	}).Methods("GET")
	// ~

	// static files
	router.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
	// ~

	port := os.Getenv("PORT")
	if port == "" {
		port = "5000"
	}
	log.Print("listening...")
	http.ListenAndServe(":"+port, middle)
}