go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/postgresql/queue.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package postgresql
    26  
    27  import (
    28  	"context"
    29  	"database/sql"
    30  
    31  	"go.temporal.io/server/common/persistence"
    32  	"go.temporal.io/server/common/persistence/sql/sqlplugin"
    33  )
    34  
    35  const (
    36  	templateEnqueueMessageQuery      = `INSERT INTO queue (queue_type, message_id, message_payload, message_encoding) VALUES(:queue_type, :message_id, :message_payload, :message_encoding)`
    37  	templateGetMessageQuery          = `SELECT message_id, message_payload, message_encoding FROM queue WHERE queue_type = $1 and message_id = $2`
    38  	templateGetMessagesQuery         = `SELECT message_id, message_payload, message_encoding FROM queue WHERE queue_type = $1 and message_id > $2 and message_id <= $3 ORDER BY message_id ASC LIMIT $4`
    39  	templateDeleteMessageQuery       = `DELETE FROM queue WHERE queue_type = $1 and message_id = $2`
    40  	templateRangeDeleteMessagesQuery = `DELETE FROM queue WHERE queue_type = $1 and message_id > $2 and message_id <= $3`
    41  
    42  	templateGetLastMessageIDQuery = `SELECT message_id FROM queue WHERE message_id >= (SELECT message_id FROM queue WHERE queue_type=$1 ORDER BY message_id DESC LIMIT 1) FOR UPDATE`
    43  
    44  	templateCreateQueueMetadataQuery = `INSERT INTO queue_metadata (queue_type, data, data_encoding, version) VALUES(:queue_type, :data, :data_encoding, :version)`
    45  	templateUpdateQueueMetadataQuery = `UPDATE queue_metadata SET data = :data, data_encoding = :data_encoding, version = :version+1 WHERE queue_type = :queue_type and version = :version`
    46  	templateGetQueueMetadataQuery    = `SELECT data, data_encoding, version from queue_metadata WHERE queue_type = $1`
    47  	templateLockQueueMetadataQuery   = templateGetQueueMetadataQuery + " FOR UPDATE"
    48  )
    49  
    50  // InsertIntoMessages inserts a new row into queue table
    51  func (pdb *db) InsertIntoMessages(
    52  	ctx context.Context,
    53  	row []sqlplugin.QueueMessageRow,
    54  ) (sql.Result, error) {
    55  	return pdb.conn.NamedExecContext(ctx,
    56  		templateEnqueueMessageQuery,
    57  		row,
    58  	)
    59  }
    60  
    61  func (pdb *db) SelectFromMessages(
    62  	ctx context.Context,
    63  	filter sqlplugin.QueueMessagesFilter,
    64  ) ([]sqlplugin.QueueMessageRow, error) {
    65  	var rows []sqlplugin.QueueMessageRow
    66  	err := pdb.conn.SelectContext(ctx,
    67  		&rows,
    68  		templateGetMessageQuery,
    69  		filter.QueueType,
    70  		filter.MessageID,
    71  	)
    72  	return rows, err
    73  }
    74  
    75  func (pdb *db) RangeSelectFromMessages(
    76  	ctx context.Context,
    77  	filter sqlplugin.QueueMessagesRangeFilter,
    78  ) ([]sqlplugin.QueueMessageRow, error) {
    79  	var rows []sqlplugin.QueueMessageRow
    80  	err := pdb.conn.SelectContext(ctx,
    81  		&rows,
    82  		templateGetMessagesQuery,
    83  		filter.QueueType,
    84  		filter.MinMessageID,
    85  		filter.MaxMessageID,
    86  		filter.PageSize,
    87  	)
    88  	return rows, err
    89  }
    90  
    91  // DeleteFromMessages deletes message with a messageID from the queue
    92  func (pdb *db) DeleteFromMessages(
    93  	ctx context.Context,
    94  	filter sqlplugin.QueueMessagesFilter,
    95  ) (sql.Result, error) {
    96  	return pdb.conn.ExecContext(ctx,
    97  		templateDeleteMessageQuery,
    98  		filter.QueueType,
    99  		filter.MessageID,
   100  	)
   101  }
   102  
   103  // RangeDeleteFromMessages deletes messages before messageID from the queue
   104  func (pdb *db) RangeDeleteFromMessages(
   105  	ctx context.Context,
   106  	filter sqlplugin.QueueMessagesRangeFilter,
   107  ) (sql.Result, error) {
   108  	return pdb.conn.ExecContext(ctx,
   109  		templateRangeDeleteMessagesQuery,
   110  		filter.QueueType,
   111  		filter.MinMessageID,
   112  		filter.MaxMessageID,
   113  	)
   114  }
   115  
   116  // GetLastEnqueuedMessageIDForUpdate returns the last enqueued message ID
   117  func (pdb *db) GetLastEnqueuedMessageIDForUpdate(
   118  	ctx context.Context,
   119  	queueType persistence.QueueType,
   120  ) (int64, error) {
   121  	var lastMessageID int64
   122  	err := pdb.conn.GetContext(ctx,
   123  		&lastMessageID,
   124  		templateGetLastMessageIDQuery,
   125  		queueType,
   126  	)
   127  	return lastMessageID, err
   128  }
   129  
   130  func (pdb *db) InsertIntoQueueMetadata(
   131  	ctx context.Context,
   132  	row *sqlplugin.QueueMetadataRow,
   133  ) (sql.Result, error) {
   134  	return pdb.conn.NamedExecContext(ctx,
   135  		templateCreateQueueMetadataQuery,
   136  		row,
   137  	)
   138  }
   139  
   140  func (pdb *db) UpdateQueueMetadata(
   141  	ctx context.Context,
   142  	row *sqlplugin.QueueMetadataRow,
   143  ) (sql.Result, error) {
   144  	return pdb.conn.NamedExecContext(ctx,
   145  		templateUpdateQueueMetadataQuery,
   146  		row,
   147  	)
   148  }
   149  
   150  func (pdb *db) SelectFromQueueMetadata(
   151  	ctx context.Context,
   152  	filter sqlplugin.QueueMetadataFilter,
   153  ) (*sqlplugin.QueueMetadataRow, error) {
   154  	var row sqlplugin.QueueMetadataRow
   155  	err := pdb.conn.GetContext(ctx,
   156  		&row,
   157  		templateGetQueueMetadataQuery,
   158  		filter.QueueType,
   159  	)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  	return &row, err
   164  }
   165  
   166  func (pdb *db) LockQueueMetadata(
   167  	ctx context.Context,
   168  	filter sqlplugin.QueueMetadataFilter,
   169  ) (*sqlplugin.QueueMetadataRow, error) {
   170  	var row sqlplugin.QueueMetadataRow
   171  	err := pdb.conn.GetContext(ctx,
   172  		&row,
   173  		templateLockQueueMetadataQuery,
   174  		filter.QueueType,
   175  	)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	return &row, err
   180  }