github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/query_gen/install.go (about)

     1  package qgen
     2  
     3  var Install *installer
     4  
     5  func init() {
     6  	Install = &installer{instructions: []DBInstallInstruction{}}
     7  }
     8  
     9  type DBInstallInstruction struct {
    10  	Table    string
    11  	Contents string
    12  	Type     string
    13  }
    14  
    15  // TODO: Add methods to this to construct it OO-like
    16  type DBInstallTable struct {
    17  	Name      string
    18  	Charset   string
    19  	Collation string
    20  	Columns   []DBTableColumn
    21  	Keys      []DBTableKey
    22  }
    23  
    24  // A set of wrappers around the generator methods, so we can use this in the installer
    25  // TODO: Re-implement the query generation, query builder and installer adapters as layers on-top of a query text adapter
    26  type installer struct {
    27  	adapter      Adapter
    28  	instructions []DBInstallInstruction
    29  	tables       []*DBInstallTable // TODO: Use this in Record() in the next commit to allow us to auto-migrate settings rather than manually patching them in on upgrade
    30  	plugins      []QueryPlugin
    31  }
    32  
    33  func (i *installer) SetAdapter(name string) error {
    34  	a, err := GetAdapter(name)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	i.SetAdapterInstance(a)
    39  	return nil
    40  }
    41  
    42  func (i *installer) SetAdapterInstance(a Adapter) {
    43  	i.adapter = a
    44  	i.instructions = []DBInstallInstruction{}
    45  }
    46  
    47  func (i *installer) AddPlugins(plugins ...QueryPlugin) {
    48  	i.plugins = append(i.plugins, plugins...)
    49  }
    50  
    51  func (i *installer) CreateTable(table, charset, collation string, cols []DBTableColumn, keys []DBTableKey) error {
    52  	tableStruct := &DBInstallTable{table, charset, collation, cols, keys}
    53  	err := i.RunHook("CreateTableStart", tableStruct)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	res, err := i.adapter.CreateTable("", table, charset, collation, cols, keys)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	err = i.RunHook("CreateTableAfter", tableStruct)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	i.instructions = append(i.instructions, DBInstallInstruction{table, res, "create-table"})
    66  	i.tables = append(i.tables, tableStruct)
    67  	return nil
    68  }
    69  
    70  // TODO: Let plugins manipulate the parameters like in CreateTable
    71  func (i *installer) AddIndex(table, iname, colName string) error {
    72  	err := i.RunHook("AddIndexStart", table, iname, colName)
    73  	if err != nil {
    74  		return err
    75  	}
    76  	res, err := i.adapter.AddIndex("", table, iname, colName)
    77  	if err != nil {
    78  		return err
    79  	}
    80  	err = i.RunHook("AddIndexAfter", table, iname, colName)
    81  	if err != nil {
    82  		return err
    83  	}
    84  	i.instructions = append(i.instructions, DBInstallInstruction{table, res, "index"})
    85  	return nil
    86  }
    87  
    88  func (i *installer) AddKey(table, col string, key DBTableKey) error {
    89  	err := i.RunHook("AddKeyStart", table, col, key)
    90  	if err != nil {
    91  		return err
    92  	}
    93  	res, err := i.adapter.AddKey("", table, col, key)
    94  	if err != nil {
    95  		return err
    96  	}
    97  	err = i.RunHook("AddKeyAfter", table, col, key)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	i.instructions = append(i.instructions, DBInstallInstruction{table, res, "key"})
   102  	return nil
   103  }
   104  
   105  // TODO: Let plugins manipulate the parameters like in CreateTable
   106  func (i *installer) SimpleInsert(table, columns, fields string) error {
   107  	err := i.RunHook("SimpleInsertStart", table, columns, fields)
   108  	if err != nil {
   109  		return err
   110  	}
   111  	res, err := i.adapter.SimpleInsert("", table, columns, fields)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	err = i.RunHook("SimpleInsertAfter", table, columns, fields, res)
   116  	if err != nil {
   117  		return err
   118  	}
   119  	i.instructions = append(i.instructions, DBInstallInstruction{table, res, "insert"})
   120  	return nil
   121  }
   122  
   123  func (i *installer) SimpleBulkInsert(table, cols string, fieldSet []string) error {
   124  	err := i.RunHook("SimpleBulkInsertStart", table, cols, fieldSet)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	res, err := i.adapter.SimpleBulkInsert("", table, cols, fieldSet)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	err = i.RunHook("SimpleBulkInsertAfter", table, cols, fieldSet, res)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	i.instructions = append(i.instructions, DBInstallInstruction{table, res, "bulk-insert"})
   137  	return nil
   138  }
   139  
   140  func (i *installer) RunHook(name string, args ...interface{}) error {
   141  	for _, pl := range i.plugins {
   142  		err := pl.Hook(name, args...)
   143  		if err != nil {
   144  			return err
   145  		}
   146  	}
   147  	return nil
   148  }
   149  
   150  func (i *installer) Write() error {
   151  	var inserts string
   152  	// We can't escape backticks, so we have to dump it out a file at a time
   153  	for _, instr := range i.instructions {
   154  		if instr.Type == "create-table" {
   155  			err := writeFile("./schema/"+i.adapter.GetName()+"/query_"+instr.Table+".sql", instr.Contents)
   156  			if err != nil {
   157  				return err
   158  			}
   159  		} else {
   160  			inserts += instr.Contents + ";\n"
   161  		}
   162  	}
   163  
   164  	err := writeFile("./schema/"+i.adapter.GetName()+"/inserts.sql", inserts)
   165  	if err != nil {
   166  		return err
   167  	}
   168  
   169  	for _, plugin := range i.plugins {
   170  		err := plugin.Write()
   171  		if err != nil {
   172  			return err
   173  		}
   174  	}
   175  
   176  	return nil
   177  }