<commit_before>// Copyright 2017 Stratumn SAS. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package postgresstore

import (
	"database/sql"
	"encoding/json"

	"github.com/lib/pq"
	"github.com/stratumn/sdk/cs"
	"github.com/stratumn/sdk/store"
	"github.com/stratumn/sdk/types"
)

type reader struct {
	stmts readStmts
}

// GetSegment implements github.com/stratumn/sdk/store.Adapter.GetSegment.
func (a *reader) GetSegment(linkHash *types.Bytes32) (*cs.Segment, error) {
	var (
		data    string
		segment cs.Segment
	)

	if err := a.stmts.GetSegment.QueryRow(linkHash[:]).Scan(&data); err != nil {
		if err.Error() == notFoundError {
			return nil, nil
		}
		return nil, err
	}

	if err := json.Unmarshal([]byte(data), &segment); err != nil {
		return nil, err
	}

	return &segment, nil
}

// FindSegments implements github.com/stratumn/sdk/store.Adapter.FindSegments.
func (a *reader) FindSegments(filter *store.SegmentFilter) (cs.SegmentSlice, error) {
	var (
		rows         *sql.Rows
		err          error
		limit        = filter.Limit
		offset       = filter.Offset
		segments     = make(cs.SegmentSlice, 0, limit)
		process      = filter.Process
		linkHashes   = make([][]byte, len(filter.LinkHashes))
		prevLinkHash []byte
	)

	if filter.PrevLinkHash != nil {

		if prevLinkHashBytes, err := types.NewBytes32FromString(*filter.PrevLinkHash); prevLinkHashBytes != nil && err == nil {
			prevLinkHash = prevLinkHashBytes[:]
		}

		if len(filter.MapIDs) > 0 {
			mapIDs := pq.Array(filter.MapIDs)
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndMapIDsAndTags.Query(prevLinkHash, mapIDs, tags, offset, limit, process)
			} else {
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndMapIDs.Query(prevLinkHash, mapIDs, offset, limit, process)
			}
		} else {
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndTags.Query(prevLinkHash, tags, offset, limit, process)
			} else {
				rows, err = a.stmts.FindSegmentsWithPrevLinkHash.Query(prevLinkHash, offset, limit, process)
			}
		}
	} else if len(filter.LinkHashes) > 0 {
		for i, linkHash := range filter.LinkHashes {
			linkHashes[i] = linkHash[:]
		}
		linkHashesArray := pq.Array(linkHashes)
		if len(filter.MapIDs) > 0 {
			mapIDs := pq.Array(filter.MapIDs)
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithLinkHashesAndMapIDsAndTags.Query(linkHashesArray, mapIDs, tags, offset, limit, process)<commit_msg>postgresstore: fix FindSegments with linkHashes<commit_after>// Copyright 2017 Stratumn SAS. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package postgresstore

import (
	"database/sql"
	"encoding/json"

	"github.com/lib/pq"
	"github.com/stratumn/sdk/cs"
	"github.com/stratumn/sdk/store"
	"github.com/stratumn/sdk/types"
)

type reader struct {
	stmts readStmts
}

// GetSegment implements github.com/stratumn/sdk/store.Adapter.GetSegment.
func (a *reader) GetSegment(linkHash *types.Bytes32) (*cs.Segment, error) {
	var (
		data    string
		segment cs.Segment
	)

	if err := a.stmts.GetSegment.QueryRow(linkHash[:]).Scan(&data); err != nil {
		if err.Error() == notFoundError {
			return nil, nil
		}
		return nil, err
	}

	if err := json.Unmarshal([]byte(data), &segment); err != nil {
		return nil, err
	}

	return &segment, nil
}

// FindSegments implements github.com/stratumn/sdk/store.Adapter.FindSegments.
func (a *reader) FindSegments(filter *store.SegmentFilter) (cs.SegmentSlice, error) {
	var (
		rows         *sql.Rows
		err          error
		limit        = filter.Limit
		offset       = filter.Offset
		segments     = make(cs.SegmentSlice, 0, limit)
		process      = filter.Process
		prevLinkHash []byte
	)

	if filter.PrevLinkHash != nil {

		if prevLinkHashBytes, err := types.NewBytes32FromString(*filter.PrevLinkHash); prevLinkHashBytes != nil && err == nil {
			prevLinkHash = prevLinkHashBytes[:]
		}

		if len(filter.MapIDs) > 0 {
			mapIDs := pq.Array(filter.MapIDs)
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndMapIDsAndTags.Query(prevLinkHash, mapIDs, tags, offset, limit, process)
			} else {
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndMapIDs.Query(prevLinkHash, mapIDs, offset, limit, process)
			}
		} else {
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithPrevLinkHashAndTags.Query(prevLinkHash, tags, offset, limit, process)
			} else {
				rows, err = a.stmts.FindSegmentsWithPrevLinkHash.Query(prevLinkHash, offset, limit, process)
			}
		}
	} else if len(filter.LinkHashes) > 0 {
		linkHashesArray := pq.Array(filter.LinkHashes)
		if len(filter.MapIDs) > 0 {
			mapIDs := pq.Array(filter.MapIDs)
			if len(filter.Tags) > 0 {
				tags := pq.Array(filter.Tags)
				rows, err = a.stmts.FindSegmentsWithLinkHashesAndMapIDsAndTags.Query(linkHashesArray, mapIDs, tags, offset, limit, process)
{'fraction_non_alphanumeric': 0.12119717151784246, 'fraction_numerical': 0.006248972208518336, 'mean_word_length': 3.635670731707317, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5967516', 'n_tokens_mistral': 2200, 'n_tokens_neox': 2005, 'n_words': 515}