github.com/RevenueMonster/sqlike@v1.0.6/sqlike/index.go (about)

     1  package sqlike
     2  
     3  import (
     4  	"context"
     5  
     6  	semver "github.com/Masterminds/semver/v3"
     7  	sqldialect "github.com/RevenueMonster/sqlike/sql/dialect"
     8  	sqldriver "github.com/RevenueMonster/sqlike/sql/driver"
     9  	sqlstmt "github.com/RevenueMonster/sqlike/sql/stmt"
    10  	"github.com/RevenueMonster/sqlike/sqlike/indexes"
    11  	"github.com/RevenueMonster/sqlike/sqlike/logs"
    12  )
    13  
    14  var mysql8 = semver.MustParse("8.0.0")
    15  
    16  // Index :
    17  type Index struct {
    18  	Name     string
    19  	Type     string
    20  	IsUnique bool
    21  }
    22  
    23  // IndexView :
    24  type IndexView struct {
    25  	tb          *Table
    26  	supportDesc *bool
    27  }
    28  
    29  // List :
    30  func (idv *IndexView) List(ctx context.Context) ([]Index, error) {
    31  	return idv.tb.ListIndexes(ctx)
    32  }
    33  
    34  // CreateOne :
    35  func (idv *IndexView) CreateOne(ctx context.Context, idx indexes.Index) error {
    36  	return idv.Create(ctx, []indexes.Index{idx})
    37  }
    38  
    39  // Create :
    40  func (idv *IndexView) Create(ctx context.Context, idxs []indexes.Index) error {
    41  	for _, idx := range idxs {
    42  		if idx.Type != indexes.MultiValued && len(idx.Columns) < 1 {
    43  			return ErrNoColumn
    44  		}
    45  	}
    46  	stmt := sqlstmt.AcquireStmt(idv.tb.dialect)
    47  	defer sqlstmt.ReleaseStmt(stmt)
    48  	idv.tb.dialect.CreateIndexes(stmt, idv.tb.dbName, idv.tb.name, idxs, idv.isSupportDesc())
    49  	_, err := sqldriver.Execute(
    50  		ctx,
    51  		idv.tb.driver,
    52  		stmt,
    53  		idv.tb.logger,
    54  	)
    55  	return err
    56  }
    57  
    58  // CreateOneIfNotExists :
    59  func (idv *IndexView) CreateOneIfNotExists(ctx context.Context, idx indexes.Index) error {
    60  	return idv.CreateIfNotExists(ctx, []indexes.Index{idx})
    61  }
    62  
    63  // CreateIfNotExists :
    64  func (idv *IndexView) CreateIfNotExists(ctx context.Context, idxs []indexes.Index) error {
    65  	cols := make([]indexes.Index, 0, len(idxs))
    66  	stmt := sqlstmt.AcquireStmt(idv.tb.dialect)
    67  	defer sqlstmt.ReleaseStmt(stmt)
    68  	for _, idx := range idxs {
    69  		if len(idx.Columns) < 1 {
    70  			return ErrNoColumn
    71  		}
    72  		idv.tb.dialect.HasIndex(stmt, idv.tb.dbName, idv.tb.name, idx)
    73  		var count int
    74  		if err := sqldriver.QueryRowContext(
    75  			ctx,
    76  			idv.tb.driver,
    77  			stmt,
    78  			idv.tb.logger,
    79  		).Scan(&count); err != nil {
    80  			return err
    81  		}
    82  		stmt.Reset()
    83  		if count > 0 {
    84  			continue
    85  		}
    86  		cols = append(cols, idx)
    87  	}
    88  	if len(cols) < 1 {
    89  		return nil
    90  	}
    91  	idv.tb.dialect.CreateIndexes(stmt, idv.tb.dbName, idv.tb.name, cols, idv.isSupportDesc())
    92  	_, err := sqldriver.Execute(
    93  		ctx,
    94  		idv.tb.driver,
    95  		stmt,
    96  		idv.tb.logger,
    97  	)
    98  	return err
    99  }
   100  
   101  // DropOne :
   102  func (idv IndexView) DropOne(ctx context.Context, name string) error {
   103  	stmt := sqlstmt.AcquireStmt(idv.tb.dialect)
   104  	defer sqlstmt.ReleaseStmt(stmt)
   105  	idv.tb.dialect.DropIndexes(stmt, idv.tb.dbName, idv.tb.name, []string{name})
   106  	_, err := sqldriver.Execute(
   107  		ctx,
   108  		idv.tb.driver,
   109  		stmt,
   110  		idv.tb.logger,
   111  	)
   112  	return err
   113  }
   114  
   115  // DropAll :
   116  func (idv *IndexView) DropAll(ctx context.Context) error {
   117  	idxs, err := idv.List(ctx)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	names := make([]string, 0)
   122  	for _, idx := range idxs {
   123  		names = append(names, idx.Name)
   124  	}
   125  	stmt := sqlstmt.AcquireStmt(idv.tb.dialect)
   126  	defer sqlstmt.ReleaseStmt(stmt)
   127  	idv.tb.dialect.DropIndexes(stmt, idv.tb.dbName, idv.tb.name, names)
   128  	if _, err := sqldriver.Execute(
   129  		ctx,
   130  		idv.tb.driver,
   131  		stmt,
   132  		idv.tb.logger,
   133  	); err != nil {
   134  		return err
   135  	}
   136  	return nil
   137  }
   138  
   139  func (idv *IndexView) isSupportDesc() bool {
   140  	if idv.supportDesc != nil {
   141  		return *idv.supportDesc
   142  	}
   143  	flag := false
   144  	if idv.tb.client.driverName == "mysql" &&
   145  		idv.tb.client.version.GreaterThan(mysql8) {
   146  		flag = true
   147  	}
   148  	idv.supportDesc = &flag
   149  	return *idv.supportDesc
   150  }
   151  
   152  func isIndexExists(ctx context.Context, dbName, table, indexName string, driver sqldriver.Driver, dialect sqldialect.Dialect, logger logs.Logger) (bool, error) {
   153  	stmt := sqlstmt.AcquireStmt(dialect)
   154  	defer sqlstmt.ReleaseStmt(stmt)
   155  	dialect.HasIndexByName(stmt, dbName, table, indexName)
   156  	var count int
   157  	if err := sqldriver.QueryRowContext(
   158  		ctx,
   159  		driver,
   160  		stmt,
   161  		logger,
   162  	).Scan(&count); err != nil {
   163  		return false, err
   164  	}
   165  	return count > 0, nil
   166  }