@@ -9,11 +9,13 @@ import (
9
9
"io"
10
10
"reflect"
11
11
"strconv"
12
+ "strings"
12
13
"time"
13
14
14
15
"github.com/VividCortex/mysqlerr"
15
16
"github.com/clems4ever/go-graphkb/internal/knowledge"
16
17
"github.com/clems4ever/go-graphkb/internal/schema"
18
+ "github.com/clems4ever/go-graphkb/internal/utils"
17
19
mysql "github.com/go-sql-driver/mysql"
18
20
"github.com/golang-collections/go-datastructures/queue"
19
21
"github.com/sirupsen/logrus"
@@ -616,58 +618,85 @@ func (m *MariaDB) Query(ctx context.Context, sql knowledge.SQLTranslation) (*kno
616
618
}
617
619
618
620
func (m * MariaDB ) GetAssetSources (ctx context.Context , ids []string ) (map [string ][]string , error ) {
619
- stmt , err := m .db .PrepareContext (ctx , `
620
- SELECT sources.name FROM sources
621
- INNER JOIN assets_by_source ON sources.id = assets_by_source.source_id
622
- WHERE asset_id = ?` )
623
- if err != nil {
624
- return nil , fmt .Errorf ("Unable to prepare statement for retrieving asset sources: %w" , err )
621
+ if len (ids ) == 0 {
622
+ return nil , nil
625
623
}
624
+
625
+ args := make ([]interface {}, len (ids ))
626
+ for i , id := range ids {
627
+ args [i ] = id
628
+ }
629
+
626
630
idsSet := make (map [string ][]string )
627
- for _ , id := range ids {
628
- row , err := stmt .QueryContext (ctx , id )
631
+ argsSlices := utils .ChunkSlice (args , 500 ).([][]interface {})
632
+
633
+ for _ , argsSlice := range argsSlices {
634
+ stmt , err := m .db .PrepareContext (ctx , `
635
+ SELECT asset_id, sources.name FROM sources
636
+ INNER JOIN assets_by_source ON sources.id = assets_by_source.source_id
637
+ WHERE asset_id IN (?` + strings .Repeat (",?" , len (argsSlice )- 1 )+ `)` )
629
638
if err != nil {
630
- return nil , fmt .Errorf ("Unable to retrieve sources for asset id %s: %w" , id , err )
639
+ return nil , fmt .Errorf ("Unable to prepare statement for retrieving asset sources: %w" , err )
640
+ }
641
+ row , err := stmt .QueryContext (ctx , argsSlice ... )
642
+ if err != nil {
643
+ return nil , fmt .Errorf ("Unable to retrieve sources for assets: %w" , err )
631
644
}
632
-
633
- idsSet [id ] = []string {}
634
645
635
646
var source string
647
+ var assetId uint64
648
+
636
649
for row .Next () {
637
- err = row .Scan (& source )
650
+ err = row .Scan (& assetId , & source )
638
651
if err != nil {
639
652
return nil , fmt .Errorf ("Unable to scan row of asset source: %w" , err )
640
653
}
641
- idsSet [id ] = append (idsSet [id ], source )
654
+ assetIdStr := fmt .Sprintf ("%d" , assetId )
655
+ if _ , ok := idsSet [assetIdStr ]; ! ok {
656
+ idsSet [assetIdStr ] = []string {}
657
+ }
658
+ idsSet [assetIdStr ] = append (idsSet [assetIdStr ], source )
642
659
}
643
660
}
644
661
return idsSet , nil
645
662
}
646
663
647
664
func (m * MariaDB ) GetRelationSources (ctx context.Context , ids []string ) (map [string ][]string , error ) {
648
- stmt , err := m . db . PrepareContext ( ctx , `
649
- SELECT sources.name FROM sources
650
- INNER JOIN relations_by_source ON sources.id = relations_by_source.source_id
651
- WHERE relation_id = ?` )
652
- if err != nil {
653
- return nil , fmt . Errorf ( "Unable to prepare statement for retrieving relation sources: %w" , err )
665
+ if len ( ids ) == 0 {
666
+ return nil , nil
667
+ }
668
+ args := make ([] interface {}, len ( ids ) )
669
+ for i , id := range ids {
670
+ args [ i ] = id
654
671
}
655
672
idsSet := make (map [string ][]string )
656
- for _ , id := range ids {
657
- row , err := stmt .QueryContext (ctx , id )
673
+
674
+ argsSlices := utils .ChunkSlice (args , 500 ).([][]interface {})
675
+
676
+ for _ , argsSlice := range argsSlices {
677
+ stmt , err := m .db .PrepareContext (ctx , `
678
+ SELECT relation_id, sources.name FROM sources
679
+ INNER JOIN relations_by_source ON sources.id = relations_by_source.source_id
680
+ WHERE relation_id IN (?` + strings .Repeat (",?" , len (argsSlice )- 1 )+ `)` )
658
681
if err != nil {
659
- return nil , fmt .Errorf ("Unable to retrieve sources for relation id %s: %w" , id , err )
682
+ return nil , fmt .Errorf ("Unable to prepare statement for retrieving relation sources: %w" , err )
683
+ }
684
+ row , err := stmt .QueryContext (ctx , argsSlice ... )
685
+ if err != nil {
686
+ return nil , fmt .Errorf ("Unable to retrieve sources for relations: %w" , err )
660
687
}
661
-
662
- idsSet [id ] = []string {}
663
688
664
689
var source string
690
+ var relationId string
665
691
for row .Next () {
666
- err = row .Scan (& source )
692
+ err = row .Scan (& relationId , & source )
667
693
if err != nil {
668
694
return nil , fmt .Errorf ("Unable to scan row of relation source: %w" , err )
669
695
}
670
- idsSet [id ] = append (idsSet [id ], source )
696
+ if _ , ok := idsSet [relationId ]; ! ok {
697
+ idsSet [relationId ] = []string {}
698
+ }
699
+ idsSet [relationId ] = append (idsSet [relationId ], source )
671
700
}
672
701
}
673
702
return idsSet , nil
0 commit comments