func(s*sqliteStorage)findExactHashes(statement*sql.Stmt,items...interface{})([]sqliteHash,error){// exact matches are also found by partial matches. Don't bother with exact matches so we don't have to de-duplicate
hashes:=[]sqliteHash{}
rows,err:=statement.Query(items...)
iferr!=nil{
returnhashes,err
}
forrows.Next(){
var(
r=sqliteHash{Result:Result{IDs:make(IDList)}}
hint64
)
err=rows.Scan(&r.hashid,&h,&r.Hash.Kind)
iferr!=nil{
rows.Close()
returnhashes,err
}
r.Hash.Hash=uint64(h)
hashes=append(hashes,r)
}
rows.Close()
statement,err=s.db.PrepareContext(context.Background(),`SELECT IDS.domain, IDs.id FROM IDs JOIN id_hash ON IDs.rowid = id_hash.idid WHERE (id_hash.hashid=?) ORDER BY IDs.domain, IDs.ID;`)
iferr!=nil{
returnhashes,err
}
for_,hash:=rangehashes{
rows,err:=statement.Query(hash.hashid)
iferr!=nil{
returnhashes,err
}
forrows.Next(){
varsourceSource
varidstring
err:=rows.Scan(&source,&id)
iferr!=nil{
returnhashes,err
}
hash.IDs[source]=append(hash.IDs[source],id)
}
rows.Close()
}
returnhashes,nil
}
func(s*sqliteStorage)findPartialHashes(maxint,search_hashint64,kindgoimagehash.Kind)([]sqliteHash,error){// exact matches are also found by partial matches. Don't bother with exact matches so we don't have to de-duplicate
statement,err=s.db.PrepareContext(context.Background(),`SELECT DISTINCT IDS.domain, IDs.id, id_hash.hashid FROM IDs JOIN id_hash ON IDs.rowid = id_hash.idid WHERE (id_hash.hashid in (`+strings.TrimRight(strings.Repeat("?,",len(hashes)),",")+`)) ORDER BY IDs.domain, IDs.ID;`)
ifexactOnly{// exact matches are also found by partial matches. Don't bother with exact matches so we don't have to de-duplicate
statement,err:=s.db.Prepare(`SELECT rowid,hash,kind FROM Hashes WHERE `+strings.TrimSuffix(strings.Repeat("(hash=? AND kind=?) OR",len(hashes)),"OR")+`ORDER BY kind,hash;`)
_,err=tx.Exec(`INSERT INTO id_hash (hashid,idid) VALUES `+strings.TrimSuffix(strings.Repeat("(?, ?),",len(hash_ids)),",")+` ON CONFLICT DO NOTHING;`,ids...)
rows,err:=conn.QueryContext(context.Background(),"SELECT IDs.domain,IDs.id,Hashes.hash,Hashes.kind FROM Hashes JOIN id_hash ON id_hash.hashid = hashes.rowid JOIN IDs ON IDs.rowid = id_hash.idid ORDER BY IDs.ID,Hashes.kind,Hashes.hash;")
_,err:=s.db.Exec(`INSERT INTO IDs domain,id VALUES (?,?)`,ids.NewID.Domain,ids.NewID.ID)
iferr!=nil{
panic(err)
}
rows,err:=s.db.Query(`SELECT idid FROM IDs WHERE domain=? AND id=?`,ids.NewID.Domain,ids.NewID.ID)
iferr!=nil&&!errors.Is(err,sql.ErrNoRows){
panic(err)
}
ifrows.Next(){
rows.Scan(&newIDID)
}else{
panic("Unable to insert New ID into database")
}
rows.Close()
rows,err=s.db.Query(`SELECT idid FROM IDs WHERE domain=? AND id=?`,ids.OldID.Domain,ids.OldID.ID)
iferr!=nil&&!errors.Is(err,sql.ErrNoRows){
panic(err)
}
ifrows.Next(){
rows.Scan(&oldIDID)
}else{
continue
}
_,err=s.db.Exec(`INSERT INTO id_hash (hashid, id_id) SELECT hashid,? FROM id_hash where id_id=?`,newIDID,oldIDID)
iferr!=nil{
panic(err)
}
}
}
func(s*sqliteStorage)GetIDs(idID)IDList{
varididint
rows,err:=s.db.Query(`SELECT idid FROM IDs WHERE domain=? AND id=?`,id.Domain,id.ID)
iferr!=nil&&!errors.Is(err,sql.ErrNoRows){
panic(err)
}
ifrows.Next(){
rows.Scan(&idid)
}else{
returnnil
}
rows,err=s.db.Query(`SELECT id_hash FROM id_hash WHERE id_id=?`,idid)
iferr!=nil&&!errors.Is(err,sql.ErrNoRows){
panic(err)
}
varhashIDs[]interface{}
forrows.Next(){
varhashIDint
rows.Scan(&hashID)
hashIDs=append(hashIDs,hashID)
}
rows.Close()
IDs:=make(IDList)
rows,err=s.db.Query(`SELECT IDs.domain,IDs.id FROM id_hash JOIN IDs ON id_hash.idid==IDs.idid WHERE hash_id in (`+strings.TrimRight(strings.Repeat("?,",len(hashIDs)),",")+`)`,hashIDs...)