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 }