github.com/acoshift/pgsql@v0.15.3/pgmodel/do_test.go (about)

     1  package pgmodel_test
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/acoshift/pgsql"
    12  	"github.com/acoshift/pgsql/pgctx"
    13  	"github.com/acoshift/pgsql/pgmodel"
    14  	"github.com/acoshift/pgsql/pgstmt"
    15  )
    16  
    17  func TestDo_SelectModel(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	db := open(t)
    21  	defer db.Close()
    22  
    23  	ctx := context.Background()
    24  	ctx = pgctx.NewContext(ctx, db)
    25  
    26  	_, err := db.Exec(`
    27  		drop table if exists test_pgmodel_select;
    28  		create table test_pgmodel_select (
    29  			id int primary key,
    30  			value varchar not null,
    31  			created_at timestamptz not null default now()
    32  		);
    33  		insert into test_pgmodel_select (id, value)
    34  		values (1, 'value 1'),
    35  			   (2, 'value 2');
    36  	`)
    37  	assert.NoError(t, err)
    38  
    39  	{
    40  		var m selectModel
    41  		err = pgmodel.Do(ctx, &m, pgmodel.Equal("id", 2))
    42  		assert.NoError(t, err)
    43  		assert.Equal(t, int64(2), m.ID)
    44  		assert.Equal(t, "value 2", m.Value)
    45  		assert.NotEmpty(t, m.CreatedAt)
    46  	}
    47  
    48  	{
    49  		var m selectModel
    50  		err = pgmodel.Do(ctx, &m, pgmodel.Equal("id", 99))
    51  		assert.Equal(t, sql.ErrNoRows, err)
    52  		assert.Empty(t, m)
    53  	}
    54  
    55  	{
    56  		var ms []*selectModel
    57  		err = pgmodel.Do(ctx, &ms, pgmodel.OrderBy("id desc"), pgmodel.Limit(2))
    58  		assert.NoError(t, err)
    59  		if assert.Len(t, ms, 2) {
    60  			assert.Equal(t, int64(2), ms[0].ID)
    61  			assert.Equal(t, int64(1), ms[1].ID)
    62  		}
    63  	}
    64  
    65  	{
    66  		var m selectModel
    67  		err = pgmodel.Do(ctx, &m, filterError{})
    68  		assert.Error(t, err)
    69  		_, ok := err.(filterError)
    70  		assert.True(t, ok)
    71  	}
    72  }
    73  
    74  type selectModel struct {
    75  	ID        int64
    76  	Value     string
    77  	CreatedAt time.Time
    78  }
    79  
    80  func (m *selectModel) Select(b pgstmt.SelectStatement) {
    81  	b.Columns("id", "value", "created_at")
    82  	b.From("test_pgmodel_select")
    83  }
    84  
    85  func (m *selectModel) Scan(scan pgsql.Scanner) error {
    86  	return scan(&m.ID, &m.Value, &m.CreatedAt)
    87  }
    88  
    89  func TestDo_UpdateModel(t *testing.T) {
    90  	t.Parallel()
    91  
    92  	db := open(t)
    93  	defer db.Close()
    94  
    95  	ctx := context.Background()
    96  	ctx = pgctx.NewContext(ctx, db)
    97  
    98  	_, err := db.Exec(`
    99  		drop table if exists test_pgmodel_update;
   100  		create table test_pgmodel_update (
   101  			id int primary key,
   102  			value varchar not null,
   103  			created_at timestamptz not null default now(),
   104  			updated_at timestamptz
   105  		);
   106  		insert into test_pgmodel_update (id, value)
   107  		values (1, 'value 1'),
   108  			   (2, 'value 2');
   109  	`)
   110  	assert.NoError(t, err)
   111  
   112  	{
   113  		err = pgmodel.Do(ctx, &updateModel{Value: "new value"}, pgmodel.Equal("id", 1))
   114  		assert.NoError(t, err)
   115  
   116  		var m updateSelectModel
   117  		err = pgmodel.Do(ctx, &m, pgmodel.Equal("id", 1))
   118  		assert.NoError(t, err)
   119  		assert.Equal(t, int64(1), m.ID)
   120  		assert.Equal(t, "new value", m.Value)
   121  		assert.NotEmpty(t, m.CreatedAt)
   122  		assert.NotEmpty(t, m.UpdatedAt)
   123  	}
   124  
   125  	{
   126  		u := updateModelWithReturn{Value: "update value"}
   127  		err = pgmodel.Do(ctx, &u, pgmodel.Equal("id", 2))
   128  		assert.NoError(t, err)
   129  
   130  		var m updateSelectModel
   131  		err = pgmodel.Do(ctx, &m, pgmodel.Equal("id", 2))
   132  		assert.NoError(t, err)
   133  		assert.Equal(t, int64(2), m.ID)
   134  		assert.Equal(t, "update value", m.Value)
   135  		assert.NotEmpty(t, m.CreatedAt)
   136  		assert.NotEmpty(t, m.UpdatedAt)
   137  		assert.Equal(t, m.UpdatedAt, u.Return.UpdatedAt)
   138  	}
   139  }
   140  
   141  type updateModel struct {
   142  	Value string
   143  }
   144  
   145  func (m *updateModel) Update(b pgstmt.UpdateStatement) {
   146  	b.Table("test_pgmodel_update")
   147  	b.Set("value").To(m.Value)
   148  	b.Set("updated_at").ToRaw("now()")
   149  }
   150  
   151  type updateModelWithReturn struct {
   152  	Value string
   153  
   154  	Return struct {
   155  		UpdatedAt time.Time
   156  	}
   157  }
   158  
   159  func (m *updateModelWithReturn) Update(b pgstmt.UpdateStatement) {
   160  	b.Table("test_pgmodel_update")
   161  	b.Set("value").To(m.Value)
   162  	b.Set("updated_at").ToRaw("now()")
   163  	b.Returning("updated_at")
   164  }
   165  
   166  func (m *updateModelWithReturn) Scan(scan pgsql.Scanner) error {
   167  	return scan(&m.Return.UpdatedAt)
   168  }
   169  
   170  type updateSelectModel struct {
   171  	ID        int64
   172  	Value     string
   173  	CreatedAt time.Time
   174  	UpdatedAt time.Time
   175  }
   176  
   177  func (m *updateSelectModel) Select(b pgstmt.SelectStatement) {
   178  	b.Columns("id", "value", "created_at", "updated_at")
   179  	b.From("test_pgmodel_update")
   180  }
   181  
   182  func (m *updateSelectModel) Scan(scan pgsql.Scanner) error {
   183  	return scan(&m.ID, &m.Value, &m.CreatedAt, pgsql.NullTime(&m.UpdatedAt))
   184  }
   185  
   186  func TestDo_InsertModel(t *testing.T) {
   187  	t.Parallel()
   188  
   189  	db := open(t)
   190  	defer db.Close()
   191  
   192  	ctx := context.Background()
   193  	ctx = pgctx.NewContext(ctx, db)
   194  
   195  	_, err := db.Exec(`
   196  		drop table if exists test_pgmodel_insert;
   197  		create table test_pgmodel_insert (
   198  			id int primary key,
   199  			value varchar not null,
   200  			created_at timestamptz not null default now()
   201  		);
   202  	`)
   203  	assert.NoError(t, err)
   204  
   205  	err = pgmodel.Do(ctx, &insertModel{ID: 1, Value: "value 1"})
   206  	assert.NoError(t, err)
   207  }
   208  
   209  type insertModel struct {
   210  	ID    int64
   211  	Value string
   212  }
   213  
   214  func (m *insertModel) Insert(b pgstmt.InsertStatement) {
   215  	b.Into("test_pgmodel_insert")
   216  	b.Columns("id", "value")
   217  	b.Value(m.ID, m.Value)
   218  }
   219  
   220  type filterError struct{}
   221  
   222  func (err filterError) Apply(ctx context.Context, b pgmodel.Cond) error {
   223  	return err
   224  }
   225  
   226  func (err filterError) Error() string {
   227  	return "error"
   228  }
   229