Beispiel #1
0
func (g *generator) runHeader() {
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package, "Step", "RunHeader")
	type Table struct {
		Name      string
		TableName string
	}

	data := struct {
		Package, Tick          string
		HasTypeCodeValueTables bool
		Tables                 []Table
	}{
		Package: g.tts.Package,
		Tick:    "`",
		HasTypeCodeValueTables: len(g.eavValueTables) > 0,
	}

	for _, table := range g.tables {
		data.Tables = append(data.Tables, Table{
			Name:      g.getConsistentName(table),
			TableName: g.getMagento2TableName(table),
		})
	}
	g.appendToFile(tpl.Header, data, nil)
}
Beispiel #2
0
func (g *generator) initTables() {
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package, "Step", "InitTables")
	var err error
	g.tables, err = codegen.GetTables(g.dbrConn.NewSession(), codegen.ReplaceTablePrefix(g.tts.SQLQuery))
	codegen.LogFatal(err)

	if len(g.tts.EntityTypeCodes) > 0 && g.tts.EntityTypeCodes[0] != "" {
		g.eavValueTables, err = codegen.GetEavValueTables(g.dbrConn, g.tts.EntityTypeCodes)
		codegen.LogFatal(err)

		for _, vTables := range g.eavValueTables {
			for t := range vTables {
				if false == isDuplicate(g.tables, t) {
					g.tables = append(g.tables, t)
				}
			}
		}
	}

	if g.tts.GenericsWhiteList == "" {
		return // do nothing because nothing defined, neither custom SQL nor to copy from SQLQuery field
	}
	if false == dbr.Stmt.IsSelect(g.tts.GenericsWhiteList) {
		// copy result from tables because select key word not found
		g.whiteListTables = g.tables
		return
	}

	g.whiteListTables, err = codegen.GetTables(g.dbrConn.NewSession(), codegen.ReplaceTablePrefix(g.tts.GenericsWhiteList))
	codegen.LogFatal(err)
}
Beispiel #3
0
func (g *generator) runTable() {
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package, "Step", "RunTable")
	type OneTable struct {
		Package          string
		Tick             string
		Name             string
		TableName        string
		Struct           string
		Slice            string
		Table            string
		GoColumns        codegen.Columns
		Columns          csdb.Columns
		MethodRecvPrefix string
		FindByPk         string
	}

	for _, table := range g.tables {

		columns, err := codegen.GetColumns(g.dbrConn.DB, table)
		codegen.LogFatal(err)
		codegen.LogFatal(columns.MapSQLToGoDBRType())

		name := g.getConsistentName(table)
		data := OneTable{
			Package:   g.tts.Package,
			Tick:      "`",
			Name:      name,
			TableName: g.getMagento2TableName(table), // original table name!
			Struct:    TypePrefix + name,             // getTableConstantName
			Slice:     TypePrefix + name + "Slice",   // getTableConstantName
			Table:     table,
			GoColumns: columns,
			Columns:   columns.CopyToCSDB(),
		}

		if data.Columns.PrimaryKeys().Len() > 0 {
			data.FindByPk = "FindBy" + utils.UnderscoreCamelize(data.Columns.PrimaryKeys().JoinFields("_"))
		}

		tplFuncs := template.FuncMap{
			"typePrefix": func(name string) string {
				// if the method already exists in package then add the prefix parent
				// to avoid duplicate function names.
				search := data.Slice + name
				if g.existingMethodSets.has(search) {
					return MethodRecvPrefix + name
				}
				return name
			},
			"findBy":  findBy,
			"dbrType": dbrType,
		}

		g.appendToFile(g.getGenericTemplate(table), data, tplFuncs)
	}
}
Beispiel #4
0
func detectMagentoVersion(dbrSess dbr.SessionRunner) (MageOne, MageTwo bool) {
	defer log.WhenDone().Info("Stats", "Package", "DetectMagentoVersion")
	allTables, err := codegen.GetTables(dbrSess)
	codegen.LogFatal(err)
	MageOne, MageTwo = utils.MagentoVersion(codegen.TablePrefix, allTables)

	if MageOne == MageTwo {
		codegen.LogFatal(errors.New("Cannot detect your Magento version"))
	}
	return
}
Beispiel #5
0
func (g *generator) runEAValueTables() {
	if len(g.eavValueTables) == 0 {
		return
	}
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package, "Step", "RunEAValueTables")

	data := struct {
		TypeCodeValueTables codegen.TypeCodeValueTable
	}{
		TypeCodeValueTables: g.eavValueTables,
	}

	g.appendToFile(tpl.EAValueStructure, data, nil)
}
Beispiel #6
0
func (g *generator) run() {
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package)
	defer g.wg.Done()
	g.analyzePackage()

	var err error
	g.outfile, err = os.OpenFile(g.tts.OutputFile.String(), os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	codegen.LogFatal(err)
	g.appendToFile(tpl.Copy, struct{ Package string }{Package: g.tts.Package}, nil)

	g.initTables()
	g.runHeader()
	g.runTable()
	g.runEAValueTables()
	codegen.LogFatal(g.outfile.Close())
}
Beispiel #7
0
// runCodec generates the codecs to be used later in JSON or msgpack or etc
func runCodec(pkg, outfile, readfile string) {
	defer log.WhenDone().Info("Stats", "Package", pkg, "Step", "runCodec")
	if err := codecgen.Generate(
		outfile, // outfile
		"",      // buildTag
		codecgen.GenCodecPath,
		false, // use unsafe
		"",
		regexp.MustCompile(TypePrefix+".*"), // Prefix of generated structs and slices
		true,     // delete temp files
		readfile, // read from file
	); err != nil {
		fmt.Println("codecgen.Generate Error:")
		codegen.LogFatal(err)
	}
}
Beispiel #8
0
// analyzePackage extracts from all types the method receivers and type names. If we found existing
// functions we will add a MethodRecvPrefix to the generated functions to avoid conflicts.
func (g *generator) analyzePackage() {
	defer log.WhenDone().Info("Stats", "Package", g.tts.Package, "Step", "AnalyzePackage")
	fset := token.NewFileSet()

	path := filepath.Dir(g.tts.OutputFile.String())
	pkgs, err := parser.ParseDir(fset, path, nil, parser.AllErrors)
	codegen.LogFatal(err)

	var astPkg *ast.Package
	var ok bool
	if astPkg, ok = pkgs[g.tts.Package]; !ok {
		fmt.Printf("Package %s not found in path %s. Skipping.", g.tts.Package, path)
		return
	}

	for fName, astFile := range astPkg.Files {
		if fName == g.tts.OutputFile.String() {
			// skip the generated file or we have recursion 8-)
			continue
		}
		ast.Inspect(astFile, func(n ast.Node) bool {
			switch stmt := n.(type) {
			case *ast.FuncDecl:
				if stmt.Recv != nil { // we have a method receiver and not a normal function
					switch t := stmt.Recv.List[0].Type.(type) {
					case *ast.Ident: // non-pointer-type
						if strings.Index(t.Name, TypePrefix) == 0 {
							g.existingMethodSets.add(t.Name + stmt.Name.Name) // e.g.: TableWebsiteSliceLoad where Load is the function name
						}
					case *ast.StarExpr: // pointer-type
						switch t2 := t.X.(type) {
						case *ast.Ident:
							if strings.Index(t2.Name, TypePrefix) == 0 {
								g.existingMethodSets.add(t2.Name + stmt.Name.Name) // e.g.: *TableWebsiteSliceLoad where Load is the function name
							}
						}
					}
				}
			}
			return true
		})
	}
}
Beispiel #9
0
func main() {
	defer log.WhenDone().Info("Stats")
	dbc, err := csdb.Connect()
	codegen.LogFatal(err)
	defer dbc.Close()
	var wg sync.WaitGroup

	mageV1, mageV2 := detectMagentoVersion(dbc.NewSession())

	for _, tStruct := range codegen.ConfigTableToStruct {
		go newGenerator(tStruct, dbc, &wg).setMagentoVersion(mageV1, mageV2).run()
	}

	wg.Wait()

	for _, ts := range codegen.ConfigTableToStruct {
		// due to a race condition the codec generator must run after the newGenerator() calls
		runCodec(ts.Package, ts.OutputFile.AppendName("_codec").String(), ts.OutputFile.String())
	}
}
Beispiel #10
0
// GetTables returns all tables from a database. AndWhere can be optionally applied.
// Only first index (0) will be added.
func GetTables(dbrSess dbr.SessionRunner, sql ...string) ([]string, error) {

	qry := "SHOW TABLES"
	if len(sql) > 0 && sql[0] != "" {
		if false == dbr.Stmt.IsSelect(sql[0]) {
			qry = qry + " LIKE '" + sql[0] + "'"
		} else {
			qry = sql[0]
		}
	}
	if PkgLog.IsInfo() { // this if reduces 9 allocs ...
		defer log.WhenDone(PkgLog).Info("Stats", "Package", "codegen", "Step", "GetTables", "query", qry)
	}

	sb := dbrSess.SelectBySql(qry)
	query, args, err := sb.ToSql()
	if err != nil {
		return nil, errgo.Mask(err)
	}
	rows, err := sb.Query(query, args...)
	if err != nil {
		return nil, errgo.Mask(err)
	}
	defer rows.Close()

	var tableName string
	var tableNames = make([]string, 0, 200)
	for rows.Next() {
		if err := rows.Scan(&tableName); err != nil {
			return nil, errgo.Mask(err)
		}
		tableNames = append(tableNames, tableName)
	}

	if err = rows.Err(); err != nil {
		return nil, errgo.Mask(err)
	}
	return tableNames, nil
}