github.com/wfusion/gofusion@v1.1.14/common/infra/watermill/pubsub/sql/schema.go (about)

     1  package sql
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  
     7  	"github.com/pkg/errors"
     8  
     9  	"github.com/wfusion/gofusion/common/infra/watermill"
    10  )
    11  
    12  var (
    13  	initLocker sync.Mutex
    14  )
    15  
    16  func initializeSchema(
    17  	ctx context.Context,
    18  	topic string,
    19  	logger watermill.LoggerAdapter,
    20  	db ContextExecutor,
    21  	schemaAdapter SchemaAdapter,
    22  	offsetsAdapter OffsetsAdapter,
    23  ) error {
    24  	err := validateTopicName(topic)
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	initializingQueries := schemaAdapter.SchemaInitializingQueries(topic)
    30  	if offsetsAdapter != nil {
    31  		initializingQueries = append(initializingQueries, offsetsAdapter.SchemaInitializingQueries(topic)...)
    32  	}
    33  
    34  	logger.Info("Initializing subscriber schema", watermill.LogFields{
    35  		"query": initializingQueries,
    36  	})
    37  
    38  	// postgres executing create table if not exists DDL is not safe concurrently
    39  	// issue: duplicate key value violates unique constraint "pg_class_relname_nsp_index" (SQLSTATE 23505)
    40  	initLocker.Lock()
    41  	defer initLocker.Unlock()
    42  	for _, q := range initializingQueries {
    43  		_, err := db.ExecContext(ctx, q)
    44  		if err != nil {
    45  			return errors.Wrap(err, "could not initialize schema")
    46  		}
    47  	}
    48  
    49  	return nil
    50  }