func loadFile(c *cli.Context) { fmt.Printf("loading file '%s'\n", c.Args()[0]) file, err := os.Open(c.Args()[0]) if err != nil { panic(err) } reader := csv.NewReader(file) keys, err := reader.Read() if err != nil { panic(err) } conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", ipAddress, port)) if err != nil { panic(err) } startTime := time.Now() recordCount := 0 records := []*coterie.Record{} for { values, err := reader.Read() if err != nil { break } record := make(map[string]string) for i, key := range keys { record[key] = values[i] } records = append(records, &coterie.Record{record}) recordCount++ if len(records) == 50 { if err = sendInsertRecordsMsg(records, conn); err != nil { panic(err) } records = nil } } if len(records) != 0 { if err = sendInsertRecordsMsg(records, conn); err != nil { panic(err) } } fmt.Printf("loaded %d records in %v", recordCount, time.Since(startTime)) coterieMsg := new(coterie.CoterieMsg) coterieMsg.Type = coterie.CoterieMsg_CLOSE_CONNECTION coterieMsg.CloseConnectionMsg = &coterie.CloseConnectionMsg{"finished writes"} if err = coterie.WriteCoterieMsg(coterieMsg, conn); err != nil { panic(err) } conn.Close() }
func sendInsertRecordsMsg(records []*coterie.Record, conn net.Conn) error { coterieMsg := new(coterie.CoterieMsg) coterieMsg.Type = coterie.CoterieMsg_INSERT_RECORDS coterieMsg.InsertRecordsMsg = &coterie.InsertRecordsMsg{records} if err := coterie.WriteCoterieMsg(coterieMsg, conn); err != nil { return err } rtnMsg, err := coterie.ReadCoterieMsg(conn) if err != nil { return err } if rtnMsg.Type != coterie.CoterieMsg_RESULT { return errors.New("Expecting result message") } return nil }
func query(c *cli.Context) { fmt.Println("TODO - query '", strings.Join(c.Args(), " "), "'") conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", ipAddress, port)) if err != nil { panic(err) } queryMsg := new(coterie.QueryMsg) queryMsg.FieldNames = []string{} queryMsg.Filters = []*coterie.Filter{ &coterie.Filter{ FieldName: "first_name", Type: "levenshtein", Arguments: []string{"3"}, Value: "tony", }, &coterie.Filter{ FieldName: "last_name", Type: "levenshtein", Arguments: []string{"3"}, Value: "chambers", }, } coterieMsg := new(coterie.CoterieMsg) coterieMsg.Type = coterie.CoterieMsg_QUERY coterieMsg.QueryMsg = queryMsg if err := coterie.WriteCoterieMsg(coterieMsg, conn); err != nil { panic(err) } _, err = coterie.ReadCoterieMsg(conn) if err != nil { panic(err) } fmt.Println("read records being returned") }
func handleConn(conn net.Conn, recStore *recordStore.RecordStore, dhtService *dht.DHTService) { defer conn.Close() conns := make(map[string]*net.TCPConn) for { coterieMsg, err := coterie.ReadCoterieMsg(conn) if err != nil { panic(err) } switch coterieMsg.Type { case coterie.CoterieMsg_CLOSE_CONNECTION: case coterie.CoterieMsg_INSERT_ENTRY: insertEntryMsg := coterieMsg.GetInsertEntryMsg() if err := recStore.InsertEntry(insertEntryMsg.Token, insertEntryMsg.Key, insertEntryMsg.Value); err != nil { panic(err) } continue case coterie.CoterieMsg_INSERT_RECORD: insertRecordMsg := coterieMsg.GetInsertRecordMsg() if err := recStore.InsertRecord(insertRecordMsg.Token, insertRecordMsg.GetRecord().GetEntries()); err != nil { panic(err) } continue case coterie.CoterieMsg_INSERT_RECORDS: insertRecordsMsg := coterieMsg.GetInsertRecordsMsg() for _, record := range insertRecordsMsg.GetRecords() { recordKey := recordStore.ComputeRecordToken(record.GetEntries()) recordAddress, err := dhtService.Lookup(recordKey) if err != nil { panic(err) } insertRecordMsg := new(coterie.CoterieMsg) insertRecordMsg.Type = coterie.CoterieMsg_INSERT_RECORD insertRecordMsg.InsertRecordMsg = &coterie.InsertRecordMsg{recordKey, record} recordConn := getConn(recordAddress, conns) err = coterie.WriteCoterieMsg(insertRecordMsg, recordConn) if err != nil { panic(err) } for key, value := range record.GetEntries() { entryKey := recordStore.ComputeEntryToken(key, value) entryAddress, err := dhtService.Lookup(entryKey) if err != nil { panic(err) } insertEntryMsg := new(coterie.CoterieMsg) insertEntryMsg.Type = coterie.CoterieMsg_INSERT_ENTRY insertEntryMsg.InsertEntryMsg = &coterie.InsertEntryMsg{entryKey, key, value} entryConn := getConn(entryAddress, conns) err = coterie.WriteCoterieMsg(insertEntryMsg, entryConn) if err != nil { panic(err) } } } resultMsg := new(coterie.CoterieMsg) resultMsg.Type = coterie.CoterieMsg_RESULT resultMsg.ResultMsg = &coterie.ResultMsg{true, ""} if err = coterie.WriteCoterieMsg(resultMsg, conn); err != nil { panic(err) } continue case coterie.CoterieMsg_QUERY: queryMsg := coterieMsg.GetQueryMsg() for _, filter := range queryMsg.Filters { fmt.Printf("Filter on %s ~%s(%v) %s\n", filter.FieldName, filter.Type, filter.Arguments, filter.Value) } fmt.Println("TODO - execute query") queryResultMsg := new(coterie.QueryResultMsg) queryResultMsg.Records = []*coterie.Record{} coterieMsg := new(coterie.CoterieMsg) coterieMsg.Type = coterie.CoterieMsg_QUERY_RESULT coterieMsg.QueryResultMsg = &coterie.QueryResultMsg{[]*coterie.Record{}} if err = coterie.WriteCoterieMsg(coterieMsg, conn); err != nil { panic(err) } default: fmt.Printf("TODO - handle coterie messsage type: %v\n", coterieMsg.Type) } break } closeConnectionMsg := new(coterie.CoterieMsg) closeConnectionMsg.Type = coterie.CoterieMsg_CLOSE_CONNECTION closeConnectionMsg.CloseConnectionMsg = &coterie.CloseConnectionMsg{"finished writes"} for _, conn := range conns { coterie.WriteCoterieMsg(closeConnectionMsg, conn) conn.Close() } }