func (st *storage) Update(key *openpgp.PrimaryKey, lastMD5 string) (retErr error) { tx, err := st.Begin() if err != nil { return errgo.Mask(err) } defer func() { if retErr != nil { tx.Rollback() } else { tx.Commit() } }() openpgp.Sort(key) now := time.Now().UTC() jsonKey := jsonhkp.NewPrimaryKey(key) jsonBuf, err := json.Marshal(jsonKey) keyword := strings.Join(keywords(key), " & ") _, err = tx.Exec("UPDATE keys SET mtime = $1, md5 = $2, keywords = to_tsvector($3), doc = $4 "+ "WHERE rfingerprint = $5", &now, &key.MD5, &keyword, jsonBuf, &key.RFingerprint) if err != nil { return errgo.Mask(err) } for _, subKey := range key.SubKeys { _, err := tx.Exec("INSERT INTO subkeys (rfingerprint, rsubfp) "+ "SELECT $1::TEXT, $2::TEXT WHERE NOT EXISTS (SELECT 1 FROM subkeys WHERE rsubfp = $2)", &key.RFingerprint, &subKey.RFingerprint) if err != nil { return errgo.Mask(err) } } st.Notify(hkpstorage.KeyReplaced{ OldDigest: lastMD5, NewDigest: key.MD5, }) return nil }
func (st *storage) Insert(keys []*openpgp.PrimaryKey) (n int, retErr error) { tx, err := st.Begin() if err != nil { return 0, errgo.Mask(err) } defer func() { if retErr != nil { tx.Rollback() } else { tx.Commit() } }() stmt, err := tx.Prepare("INSERT INTO keys (rfingerprint, ctime, mtime, md5, doc, keywords) " + "SELECT $1::TEXT, $2::TIMESTAMP, $3::TIMESTAMP, $4::TEXT, $5::JSONB, to_tsvector($6) " + "WHERE NOT EXISTS (SELECT 1 FROM keys WHERE rfingerprint = $1)") if err != nil { return 0, errgo.Mask(err) } defer stmt.Close() subStmt, err := tx.Prepare("INSERT INTO subkeys (rfingerprint, rsubfp) " + "SELECT $1::TEXT, $2::TEXT WHERE NOT EXISTS (SELECT 1 FROM subkeys WHERE rsubfp = $2)") if err != nil { return 0, errgo.Mask(err) } defer subStmt.Close() var result hkpstorage.InsertError for _, key := range keys { openpgp.Sort(key) now := time.Now().UTC() jsonKey := jsonhkp.NewPrimaryKey(key) jsonBuf, err := json.Marshal(jsonKey) if err != nil { result.Errors = append(result.Errors, errgo.Notef(err, "cannot serialize rfp=%q", key.RFingerprint)) continue } jsonStr := string(jsonBuf) keyword := strings.Join(keywords(key), " & ") _, err = stmt.Exec(&key.RFingerprint, &now, &now, &key.MD5, &jsonStr, &keyword) if err != nil { result.Errors = append(result.Errors, errgo.Notef(err, "cannot insert rfp=%q", key.RFingerprint)) continue } for _, subKey := range key.SubKeys { _, err = subStmt.Exec(&key.RFingerprint, &subKey.RFingerprint) if err != nil { result.Errors = append(result.Errors, errgo.Notef(err, "cannot insert rsubfp=%q", subKey.RFingerprint)) } } st.Notify(hkpstorage.KeyAdded{ Digest: key.MD5, }) n++ } if len(result.Duplicates) > 0 || len(result.Errors) > 0 { return n, result } return n, nil }