github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/database/sqlcommon/event_sql.go (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package sqlcommon
    18  
    19  import (
    20  	"context"
    21  	"database/sql"
    22  
    23  	sq "github.com/Masterminds/squirrel"
    24  	"github.com/kaleido-io/firefly/internal/i18n"
    25  	"github.com/kaleido-io/firefly/internal/log"
    26  	"github.com/kaleido-io/firefly/pkg/database"
    27  	"github.com/kaleido-io/firefly/pkg/fftypes"
    28  )
    29  
    30  var (
    31  	eventColumns = []string{
    32  		"id",
    33  		"etype",
    34  		"namespace",
    35  		"ref",
    36  		"group_hash",
    37  		"created",
    38  	}
    39  	eventFilterTypeMap = map[string]string{
    40  		"type":      "etype",
    41  		"reference": "ref",
    42  		"group":     "group_hash",
    43  	}
    44  )
    45  
    46  func (s *SQLCommon) UpsertEvent(ctx context.Context, event *fftypes.Event, allowExisting bool) (err error) {
    47  	ctx, tx, autoCommit, err := s.beginOrUseTx(ctx)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	defer s.rollbackTx(ctx, tx, autoCommit)
    52  
    53  	existing := false
    54  	if allowExisting {
    55  		// Do a select within the event to detemine if the UUID already exists
    56  		eventRows, err := s.queryTx(ctx, tx,
    57  			sq.Select("id").
    58  				From("events").
    59  				Where(sq.Eq{"id": event.ID}),
    60  		)
    61  		if err != nil {
    62  			return err
    63  		}
    64  		existing = eventRows.Next()
    65  		eventRows.Close()
    66  	}
    67  
    68  	if existing {
    69  		// Update the event
    70  		if err = s.updateTx(ctx, tx,
    71  			sq.Update("events").
    72  				Set("etype", string(event.Type)).
    73  				Set("namespace", event.Namespace).
    74  				Set("ref", event.Reference).
    75  				Set("group_hash", event.Group).
    76  				Set("created", event.Created).
    77  				Where(sq.Eq{"id": event.ID}),
    78  		); err != nil {
    79  			return err
    80  		}
    81  	} else {
    82  		sequence, err := s.insertTx(ctx, tx,
    83  			sq.Insert("events").
    84  				Columns(eventColumns...).
    85  				Values(
    86  					event.ID,
    87  					string(event.Type),
    88  					event.Namespace,
    89  					event.Reference,
    90  					event.Group,
    91  					event.Created,
    92  				),
    93  		)
    94  		if err != nil {
    95  			return err
    96  		}
    97  
    98  		s.postCommitEvent(tx, func() {
    99  			s.callbacks.EventCreated(sequence)
   100  		})
   101  
   102  	}
   103  
   104  	return s.commitTx(ctx, tx, autoCommit)
   105  }
   106  
   107  func (s *SQLCommon) eventResult(ctx context.Context, row *sql.Rows) (*fftypes.Event, error) {
   108  	var event fftypes.Event
   109  	err := row.Scan(
   110  		&event.ID,
   111  		&event.Type,
   112  		&event.Namespace,
   113  		&event.Reference,
   114  		&event.Group,
   115  		&event.Created,
   116  		// Must be added to the list of columns in all selects
   117  		&event.Sequence,
   118  	)
   119  	if err != nil {
   120  		return nil, i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "events")
   121  	}
   122  	return &event, nil
   123  }
   124  
   125  func (s *SQLCommon) GetEventByID(ctx context.Context, id *fftypes.UUID) (message *fftypes.Event, err error) {
   126  
   127  	cols := append([]string{}, eventColumns...)
   128  	cols = append(cols, s.provider.SequenceField(""))
   129  	rows, err := s.query(ctx,
   130  		sq.Select(cols...).
   131  			From("events").
   132  			Where(sq.Eq{"id": id}),
   133  	)
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  	defer rows.Close()
   138  
   139  	if !rows.Next() {
   140  		log.L(ctx).Debugf("Event '%s' not found", id)
   141  		return nil, nil
   142  	}
   143  
   144  	event, err := s.eventResult(ctx, rows)
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	return event, nil
   150  }
   151  
   152  func (s *SQLCommon) GetEvents(ctx context.Context, filter database.Filter) (message []*fftypes.Event, err error) {
   153  
   154  	cols := append([]string{}, eventColumns...)
   155  	cols = append(cols, s.provider.SequenceField(""))
   156  	query, err := s.filterSelect(ctx, "", sq.Select(cols...).From("events"), filter, eventFilterTypeMap)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  
   161  	rows, err := s.query(ctx, query)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	defer rows.Close()
   166  
   167  	events := []*fftypes.Event{}
   168  	for rows.Next() {
   169  		event, err := s.eventResult(ctx, rows)
   170  		if err != nil {
   171  			return nil, err
   172  		}
   173  		events = append(events, event)
   174  	}
   175  
   176  	return events, err
   177  
   178  }
   179  
   180  func (s *SQLCommon) UpdateEvent(ctx context.Context, id *fftypes.UUID, update database.Update) (err error) {
   181  
   182  	ctx, tx, autoCommit, err := s.beginOrUseTx(ctx)
   183  	if err != nil {
   184  		return err
   185  	}
   186  	defer s.rollbackTx(ctx, tx, autoCommit)
   187  
   188  	query, err := s.buildUpdate(sq.Update("events"), update, eventFilterTypeMap)
   189  	if err != nil {
   190  		return err
   191  	}
   192  	query = query.Where(sq.Eq{"id": id})
   193  
   194  	err = s.updateTx(ctx, tx, query)
   195  	if err != nil {
   196  		return err
   197  	}
   198  
   199  	return s.commitTx(ctx, tx, autoCommit)
   200  }