// Get a list of all members which are currently in the trash. func (m *MembershipDB) EnumerateTrashedMembers(prev string, num int32) ([]*MemberWithKey, error) { var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var r *cassandra.KeyRange = cassandra.NewKeyRange() var kss []*cassandra.KeySlice var ks *cassandra.KeySlice var rv []*MemberWithKey var err error // Fetch the protobuf column of the application column family. cp.ColumnFamily = "membership_archive" pred.ColumnNames = [][]byte{ []byte("pb_data"), } if len(prev) > 0 { var uuid cassandra.UUID if uuid, err = cassandra.ParseUUID(prev); err != nil { return rv, err } r.StartKey = append([]byte(archivePrefix), []byte(uuid)...) } else { r.StartKey = []byte(archivePrefix) } r.EndKey = []byte(archiveEnd) r.Count = num kss, err = m.conn.GetRangeSlices(cp, pred, r, cassandra.ConsistencyLevel_ONE) if err != nil { return rv, err } for _, ks = range kss { var member *MemberWithKey var scol *cassandra.ColumnOrSuperColumn var uuid cassandra.UUID = cassandra.UUIDFromBytes( ks.Key[len(archivePrefix):]) if len(ks.Columns) == 0 { continue } for _, scol = range ks.Columns { var col *cassandra.Column = scol.Column if string(col.Name) == "pb_data" { var agreement = new(MembershipAgreement) member = new(MemberWithKey) err = proto.Unmarshal(col.Value, agreement) proto.Merge(&member.Member, agreement.GetMemberData()) member.Key = uuid.String() } } if member != nil { rv = append(rv, member) } } return rv, nil }
func (self *ProductSearchAPI) ServeHTTP(w http.ResponseWriter, req *http.Request) { var err error var query string = req.FormValue("q") var rawdata []byte var res CategorizedSearchResult numRequests.Add(1) numAPIRequests.Add(1) // Check the user is in the reqeuested scope. if !self.authenticator.IsAuthenticatedScope(req, self.scope) { numDisallowedScope.Add(1) http.Error(w, "You are not in the right group to access this resource", http.StatusForbidden) return } if len(query) >= 3 { var product_results [][]byte var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var kr *cassandra.KeyRange = cassandra.NewKeyRange() var colmap map[string][]*cassandra.ColumnOrSuperColumn var slices []*cassandra.KeySlice var ire *cassandra.InvalidRequestException var ue *cassandra.UnavailableException var te *cassandra.TimedOutException var endkey []byte = []byte(query) var r *SearchResult var pos int = len(endkey) - 1 // Handle overflows for endkey[pos] == 255 && pos > 0 { endkey[pos] = 0 pos-- } // Produce endkey by incrementing the last byte of the start key. endkey[pos]++ // Search for projects with the given name. cp.ColumnFamily = "products_byname" pred.ColumnNames = [][]byte{[]byte("product")} kr.StartKey = []byte(query) kr.EndKey = endkey kr.Count = 32 // Limit to 32 results. slices, ire, ue, te, err = self.client.GetRangeSlices( cp, pred, kr, cassandra.ConsistencyLevel_ONE) if ire != nil { log.Print("Error fetching products_byname: ", ire.Why) numCassandraErrors.Add("invalid-request", 1) http.Error(w, ire.Why, http.StatusInternalServerError) return } if ue != nil { log.Print("Cassandra unavailable when fetching products_byname") numCassandraErrors.Add("invalid-request", 1) http.Error(w, "Database unavailable", http.StatusInternalServerError) return } if te != nil { log.Print("Cassandra timed out when fetching products_byname") numCassandraErrors.Add("timeout", 1) http.Error(w, "Database timed out", http.StatusInternalServerError) return } if err != nil { log.Print("OS error when fetching products_byname: ", err) numCassandraErrors.Add("generic-error", 1) http.Error(w, "OS error talking to database", http.StatusInternalServerError) return } for _, slice := range slices { for _, csc := range slice.Columns { var col *cassandra.Column = csc.Column if col == nil || !col.IsSetValue() { continue } if string(col.Name) != "product" { log.Print("Bizarre products_byname row ", string(slice.Key), " (", slice.Key, "), has ", string(col.Name), " (", col.Name, ")") continue } r = new(SearchResult) r.Name = string(slice.Key) r.Uuid = UUID(col.Value).String() res.Products = append(res.Products, r) } } // Search for projects with the given name. cp.ColumnFamily = "products_bybarcode" pred.ColumnNames = [][]byte{[]byte("product")} kr.StartKey = []byte(query) kr.EndKey = endkey kr.Count = 32 // Limit to 32 results. slices, ire, ue, te, err = self.client.GetRangeSlices( cp, pred, kr, cassandra.ConsistencyLevel_ONE) if ire != nil { log.Print("Error fetching products_bybarcode: ", ire.Why) numCassandraErrors.Add("invalid-request", 1) http.Error(w, ire.Why, http.StatusInternalServerError) return } if ue != nil { log.Print("Cassandra unavailable when fetching products_bybarcode") numCassandraErrors.Add("invalid-request", 1) http.Error(w, "Database unavailable", http.StatusInternalServerError) return } if te != nil { log.Print("Cassandra timed out when fetching products_bybarcode") numCassandraErrors.Add("timeout", 1) http.Error(w, "Database timed out", http.StatusInternalServerError) return } if err != nil { log.Print("OS error when fetching products_bybarcode: ", err) numCassandraErrors.Add("generic-error", 1) http.Error(w, "OS error talking to database", http.StatusInternalServerError) return } for _, slice := range slices { for _, csc := range slice.Columns { var col *cassandra.Column = csc.Column if col == nil || !col.IsSetValue() { continue } if string(col.Name) != "product" { log.Print("Bizarre products_bybarcode row ", string(slice.Key), " (", slice.Key, "), has ", string(col.Name), " (", col.Name, ")") continue } product_results = append(product_results, col.Value) } } // Now, fetch all the product names for products we spotted above. if len(product_results) > 0 { cp.ColumnFamily = "products" pred.ColumnNames = [][]byte{[]byte("name")} colmap, ire, ue, te, err = self.client.MultigetSlice( product_results, cp, pred, cassandra.ConsistencyLevel_ONE) if ire != nil { log.Print("Error fetching products: ", ire.Why) numCassandraErrors.Add("invalid-request", 1) http.Error(w, ire.Why, http.StatusInternalServerError) return } if ue != nil { log.Print("Cassandra unavailable when fetching products") numCassandraErrors.Add("invalid-request", 1) http.Error(w, "Database unavailable", http.StatusInternalServerError) return } if te != nil { log.Print("Cassandra timed out when fetching products") numCassandraErrors.Add("timeout", 1) http.Error(w, "Database timed out", http.StatusInternalServerError) return } if err != nil { log.Print("OS error when fetching products: ", err) numCassandraErrors.Add("generic-error", 1) http.Error(w, "OS error talking to database", http.StatusInternalServerError) return } for key, cscv := range colmap { for _, csc := range cscv { var col *cassandra.Column = csc.Column if col == nil || !col.IsSetValue() { continue } if string(col.Name) != "name" { log.Print("Cassandra returned additional column ", string(col.Name), " (", col.Name, ") for row ", key, " (", []byte(key), ")") continue } r = new(SearchResult) r.Name = string(col.Value) r.Uuid = UUID([]byte(key)).String() res.Products = append(res.Products, r) } } } // TODO(tonnerre): stub // r = new(SearchResult) // r.Name = "ACME Inc." // r.Uuid = "/vendor/acme" // res.Vendors = append(res.Vendors, r) // r = new(SearchResult) // r.Name = "Starship Factory" // r.Uuid = "/vendor/starshipfactory" // res.Vendors = append(res.Vendors, r) // r = new(SearchResult) // r.Name = "RaumZeitLabor e.V." // r.Uuid = "/vendor/rzl" // res.Vendors = append(res.Vendors, r) // r = new(SearchResult) // r.Name = "Doctor in the TARDIS" // r.Uuid = "/vendor/doctor" // res.Vendors = append(res.Vendors, r) } rawdata, err = json.Marshal(res) if err != nil { log.Print("Error marshalling JSON: ", err) numJSONMarshalErrors.Add(1) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Add("Content-type", "application/json") w.WriteHeader(http.StatusOK) _, err = w.Write(rawdata) if err != nil { log.Print("Error writing JSON response: ", err) numHTTPWriteErrors.Add(err.Error(), 1) } }
// Get a list of all membership applications currently in the database. // Returns a set of "num" entries beginning after "prev". If "criterion" is // given, it will be compared against the name of the member. func (m *MembershipDB) EnumerateMembershipRequests(criterion, prev string, num int32) ( []*MemberWithKey, error) { var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var r *cassandra.KeyRange = cassandra.NewKeyRange() var kss []*cassandra.KeySlice var ks *cassandra.KeySlice var rv []*MemberWithKey var err error // Fetch the name, street, city and fee columns of the application column family. cp.ColumnFamily = "application" pred.ColumnNames = [][]byte{ []byte("name"), []byte("street"), []byte("city"), []byte("fee"), []byte("fee_yearly"), } if len(prev) > 0 { var uuid cassandra.UUID if uuid, err = cassandra.ParseUUID(prev); err != nil { return rv, err } r.StartKey = append([]byte(applicationPrefix), []byte(uuid)...) } else { r.StartKey = []byte(applicationPrefix) } r.EndKey = []byte(applicationEnd) r.Count = num kss, err = m.conn.GetRangeSlices( cp, pred, r, cassandra.ConsistencyLevel_ONE) if err != nil { return rv, err } for _, ks = range kss { var member *MemberWithKey = new(MemberWithKey) var scol *cassandra.ColumnOrSuperColumn var uuid cassandra.UUID = cassandra.UUIDFromBytes( ks.Key[len(applicationPrefix):]) member.Key = uuid.String() if len(ks.Columns) == 0 { continue } for _, scol = range ks.Columns { var col *cassandra.Column = scol.Column if string(col.Name) == "name" { member.Name = proto.String(string(col.Value)) } else if string(col.Name) == "street" { member.Street = proto.String(string(col.Value)) } else if string(col.Name) == "city" { member.City = proto.String(string(col.Value)) } else if string(col.Name) == "fee" { member.Fee = proto.Uint64(binary.BigEndian.Uint64(col.Value)) } else if string(col.Name) == "fee_yearly" { member.FeeYearly = proto.Bool(col.Value[0] == 1) } } rv = append(rv, member) } return rv, nil }
// Get a list of all members currently in the database. Returns a set of // "num" entries beginning after "prev". // Returns a filled-out member structure and the timestamp when the // membership was approved. func (m *MembershipDB) EnumerateMembers(prev string, num int32) ( []*Member, error) { var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var r *cassandra.KeyRange = cassandra.NewKeyRange() var kss []*cassandra.KeySlice var ks *cassandra.KeySlice var rv []*Member var err error // Fetch all relevant non-protobuf columns of the members column family. cp.ColumnFamily = "members" pred.ColumnNames = [][]byte{ []byte("name"), []byte("street"), []byte("city"), []byte("country"), []byte("email"), []byte("phone"), []byte("username"), []byte("fee"), []byte("fee_yearly"), } r.StartKey = []byte(memberPrefix + prev) r.EndKey = []byte(memberEnd) r.Count = num kss, err = m.conn.GetRangeSlices( cp, pred, r, cassandra.ConsistencyLevel_ONE) if err != nil { return rv, err } for _, ks = range kss { var member *Member = new(Member) var scol *cassandra.ColumnOrSuperColumn if len(ks.Columns) == 0 { continue } member.Email = proto.String(string(ks.Key[len(memberPrefix):])) for _, scol = range ks.Columns { var col *cassandra.Column = scol.Column var colname string = string(col.Name) if colname == "name" { member.Name = proto.String(string(col.Value)) } else if colname == "street" { member.Street = proto.String(string(col.Value)) } else if colname == "city" { member.City = proto.String(string(col.Value)) } else if colname == "country" { member.Country = proto.String(string(col.Value)) } else if colname == "email" { member.Email = proto.String(string(col.Value)) } else if colname == "phone" { member.Phone = proto.String(string(col.Value)) } else if colname == "username" { member.Username = proto.String(string(col.Value)) } else if colname == "fee" { member.Fee = proto.Uint64(binary.BigEndian.Uint64(col.Value)) } else if colname == "fee_yearly" { member.FeeYearly = proto.Bool(col.Value[0] == 1) } } rv = append(rv, member) } return rv, nil }