Example #1
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)
}
Example #2
0
// getAttributeValuesForWebsites creates a map where the key is the attribute ID and
// each part of the StringEntities slice are the full attribute values for a website ID.
func getAttributeValuesForWebsites(ctx *context) map[string][]codegen.StringEntities {

	var tws store.TableWebsiteSlice
	tws.Load(ctx.dbrConn.NewSession(nil), func(sb *dbr.SelectBuilder) *dbr.SelectBuilder {
		return sb.Where("website_id > 0")
	})

	// key contains the attributeID as a string
	var aws = make(map[string][]codegen.StringEntities)
	tew, err := ctx.aat.TableEavWebsite()
	codegen.LogFatal(err)
	if tew != nil { // only for those who have a wbesite specific table
		for _, w := range tws {
			aCollection, err := codegen.LoadStringEntities(ctx.db, getAttrSelect(ctx, w.WebsiteID))
			codegen.LogFatal(err)
			for _, row := range aCollection {
				if aid, ok := row["attribute_id"]; ok {
					if nil == aws[aid] {
						aws[aid] = make([]codegen.StringEntities, 0, 200) // up to 200 websites at once
					}
					aws[aid] = append(aws[aid], row)
				} else {
					codegen.LogFatal(errgo.Newf("Column attribute_id not found in collection %#v\n", aCollection))
				}
			}
		}
	}
	return aws
}
Example #3
0
// materializeEntityType writes the data from eav_entity_type into a Go file and transforms
// Magento classes and config strings into Go functions.
// Depends on generated code from tableToStruct.
func materializeEntityType(ctx *context) {
	defer ctx.wg.Done()
	type dataContainer struct {
		ETypeData     eav.TableEntityTypeSlice
		ImportPaths   []string
		Package, Tick string
	}

	etData, err := getEntityTypeData(ctx.dbc.NewSession())
	codegen.LogFatal(err)

	tplData := &dataContainer{
		ETypeData:   etData,
		ImportPaths: getImportPaths(),
		Package:     codegen.ConfigMaterializationEntityType.Package,
		Tick:        "`",
	}

	addFM := template.FuncMap{
		"extractFuncType": codegen.ExtractFuncType,
	}

	formatted, err := codegen.GenerateCode(codegen.ConfigMaterializationEntityType.Package, tplEav, tplData, addFM)
	if err != nil {
		fmt.Printf("\n%s\n", formatted)
		codegen.LogFatal(err)
	}

	codegen.LogFatal(ioutil.WriteFile(codegen.ConfigMaterializationEntityType.OutputFile, formatted, 0600))
}
Example #4
0
// materializeAttributes ...
// Depends on generated code from tableToStruct.
func materializeAttributes(ctx *context) {
	defer ctx.wg.Done()

	// generators, order of execution is important
	var gs = []func(*context, map[string]interface{}) ([]byte, error){
		attrCopyright,
		attrImport,
		attrTypes,
		attrGetter,
		attrCollection,
	}

	etc, err := getEntityTypeData(ctx.dbrConn.NewSession(nil))
	codegen.LogFatal(err)
	for _, et := range etc {
		ctx.et = et
		ctx.aat = codegen.NewAddAttrTables(ctx.db, ctx.et.EntityTypeCode)
		data := attrGenerateData(ctx)
		var cb bytes.Buffer // code buffer
		for _, g := range gs {
			code, err := g(ctx, data)
			if err != nil {
				println(string(code))
				codegen.LogFatal(err)
			}
			cb.Write(code)
		}
		codegen.LogFatal(ioutil.WriteFile(getOutputFile(ctx.et), cb.Bytes(), 0600))
	}
}
Example #5
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)
	}
}
Example #6
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
}
Example #7
0
func (g *generator) appendToFile(tpl string, data interface{}, addFM template.FuncMap) {
	formatted, err := codegen.GenerateCode(g.tts.Package, tpl, data, addFM)
	if err != nil {
		fmt.Printf("\n%s\n", formatted)
		codegen.LogFatal(err)
	}

	if _, err := g.outfile.Write(formatted); err != nil {
		codegen.LogFatal(err)
	}
	codegen.LogFatal(g.outfile.Sync()) // flush immediately to disk to prevent a race condition
}
Example #8
0
func main() {

	fmt.Println("TODO refactor")
	os.Exit(-1)

	gen.Init()

	// Read the CLDR zip file. Autodownloading if file not found
	r := gen.OpenCLDRCoreZip()
	defer r.Close()

	d := &cldr.Decoder{}
	d.SetDirFilter("main", "supplemental")
	d.SetSectionFilter("localeDisplayNames", "numbers")
	data, err := d.DecodeZip(r)
	codegen.LogFatal(err)

	curW := &bytes.Buffer{}
	for _, loc := range data.Locales() {

		if false == codegen.ConfigLocalization.EnabledLocale.Include(loc) {
			continue
		}

		ldml, err := data.LDML(loc)
		codegen.LogFatal(err)
		fmt.Fprintf(os.Stdout, "Generating: %s\n", loc)

		curB := curBuilder{
			w:      curW,
			locale: loc,
			data:   ldml,
		}
		curB.generate()
	}

	tplData := map[string]interface{}{
		"Package":       codegen.ConfigLocalization.Package,
		"CurrencyDicts": curW.String(),
	}

	formatted, err := codegen.GenerateCode(codegen.ConfigLocalization.Package, tplCode, tplData, nil)
	if err != nil {
		fmt.Printf("\n\n%s\n\n", formatted)
		codegen.LogFatal(err)
	}

	codegen.LogFatal(ioutil.WriteFile(codegen.ConfigLocalization.OutputFile, formatted, 0600))
}
Example #9
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())
}
Example #10
0
// getEntityTypeData retrieves all EAV models from table eav_entity_type but only those listed in variable
// codegen.ConfigEntityType. It then applies the mapping data from codegen.ConfigEntityType to the entity_type struct.
// Depends on generated code from tableToStruct.
func getEntityTypeData(dbrSess *dbr.Session) (etc eav.TableEntityTypeSlice, err error) {

	s, err := eav.TableCollection.Structure(eav.TableIndexEntityType)
	if err != nil {
		return nil, errgo.Mask(err)
	}

	_, err = dbrSess.
		Select(s.AllColumnAliasQuote(s.Name)...).
		From(s.Name).
		Where("entity_type_code IN ?", codegen.ConfigEntityType.Keys()).
		LoadStructs(&etc)
	if err != nil {
		return nil, errgo.Mask(err)
	}

	for typeCode, mapData := range codegen.ConfigEntityType {
		// map the fields from the config struct to the data retrieved from the database.
		et, err := etc.GetByCode(typeCode)
		codegen.LogFatal(err)
		et.EntityModel = codegen.ParseString(mapData.EntityModel, et)
		et.AttributeModel.String = codegen.ParseString(mapData.AttributeModel, et)
		et.EntityTable.String = codegen.ParseString(mapData.EntityTable, et)
		et.IncrementModel.String = codegen.ParseString(mapData.IncrementModel, et)
		et.AdditionalAttributeTable.String = codegen.ParseString(mapData.AdditionalAttributeTable, et)
		et.EntityAttributeCollection.String = codegen.ParseString(mapData.EntityAttributeCollection, et)
	}

	return etc, nil
}
Example #11
0
func main() {
	db, dbrConn, err := csdb.Connect()
	codegen.LogFatal(err)
	defer db.Close()
	for _, tStruct := range codegen.ConfigTableToStruct {
		generateStructures(tStruct, db, dbrConn)
	}
}
Example #12
0
func newContext() *context {
	dbc, err := csdb.Connect()
	codegen.LogFatal(err)

	return &context{
		wg:        sync.WaitGroup{},
		dbc:       dbc,
		goSrcPath: build.Default.GOPATH + "/src/",
	}
}
Example #13
0
func getAttrSelect(ctx *context, websiteID int64) *dbr.SelectBuilder {

	dbrSelect, err := eav.GetAttributeSelectSql(
		ctx.dbrConn.NewSession(nil),
		ctx.aat,
		ctx.et.EntityTypeID,
		websiteID,
	)
	codegen.LogFatal(err)
	dbrSelect.OrderDir(csdb.MainTable+".attribute_code", true)

	tew, err := ctx.aat.TableEavWebsite()
	codegen.LogFatal(err)
	if websiteID > 0 && tew != nil {
		// only here in codegen used to detect any changes if an attribute value will be overridden by a website ID
		dbrSelect.Where(csdb.ScopeTable + ".website_id IS NOT NULL")
		dbrSelect.Columns = append(dbrSelect.Columns, csdb.ScopeTable+".website_id")
	}

	return dbrSelect
}
Example #14
0
func (g *generator) getGenericTemplate(tableName string) string {
	var finalTpl bytes.Buffer

	// at least we need a type definition
	if _, err := finalTpl.WriteString(tpl.Type); err != nil {
		codegen.LogFatal(err)
	}

	if false == g.whiteListTables.Include(tableName) {
		return finalTpl.String()
	}
	isAll := (g.tts.GenericsFunctions & tpl.OptAll) == tpl.OptAll

	if isAll || (g.tts.GenericsFunctions&tpl.OptSQL) == tpl.OptSQL {
		_, err := finalTpl.WriteString(tpl.SQL)
		codegen.LogFatal(err)
	}
	if isAll || (g.tts.GenericsFunctions&tpl.OptFindBy) == tpl.OptFindBy {
		_, err := finalTpl.WriteString(tpl.FindBy)
		codegen.LogFatal(err)
	}
	if isAll || (g.tts.GenericsFunctions&tpl.OptSort) == tpl.OptSort {
		_, err := finalTpl.WriteString(tpl.Sort)
		codegen.LogFatal(err)
	}
	if isAll || (g.tts.GenericsFunctions&tpl.OptSliceFunctions) == tpl.OptSliceFunctions {
		_, err := finalTpl.WriteString(tpl.SliceFunctions)
		codegen.LogFatal(err)
	}
	if isAll || (g.tts.GenericsFunctions&tpl.OptExtractFromSlice) == tpl.OptExtractFromSlice {
		_, err := finalTpl.WriteString(tpl.ExtractFromSlice)
		codegen.LogFatal(err)
	}
	return finalTpl.String()
}
Example #15
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)
	}
}
Example #16
0
func (b *curBuilder) generate() {

	var nameData = bytes.Buffer{}
	var nameIDX []uint16
	for _, cur := range b.data.Numbers.Currencies.Currency {
		var d string
		if len(cur.DisplayName) > 0 {
			d = cur.DisplayName[0].Data()
		}
		nameData.WriteString(d)
		nameIDX = append(nameIDX, uint16(nameData.Len()))
	}
	nameIDX = append(nameIDX, uint16(nameData.Len()))

	var codeData = bytes.Buffer{}
	for _, cur := range b.data.Numbers.Currencies.Currency {
		if len(cur.Type) != 3 {
			panic(fmt.Errorf("Expecting 3 character long currency code: %v\n", cur))
		}
		codeData.WriteString(cur.Type)
	}

	var symbolData = bytes.Buffer{}
	var symbolIDX []uint16
	for _, cur := range b.data.Numbers.Currencies.Currency {
		var d string
		if len(cur.Symbol) > 0 {
			d = cur.Symbol[0].Data()
		}
		symbolData.WriteString(d)
		symbolIDX = append(symbolIDX, uint16(symbolData.Len()))
	}
	symbolIDX = append(symbolIDX, uint16(symbolData.Len()))

	tplData := map[string]interface{}{
		"Locale":      b.locale,
		"Codes3":      codeData.String(),
		"NamesData":   nameData.String(),
		"NamesIDX":    nameIDX,
		"SymbolsData": symbolData.String(),
		"SymbolsIDX":  symbolIDX,
	}

	err := template.Must(template.New("tpl_code_unit").Parse(tplCodeUnit)).Execute(b.w, tplData)
	codegen.LogFatal(err)
}
Example #17
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(PkgLog).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() || strings.Contains(fName, "_fallback.go") {
			// skip the generated file (tables_generated.go) or we have recursion 8-)
			// skip also the _fallback.go files which contain the generated code
			// because those files get included if no build tag has been specified.
			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
		})
	}
}
Example #18
0
File: main.go Project: postfix/csfw
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())
	}
}
Example #19
0
func main() {
	defer log.WhenDone(PkgLog).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
	//		// TODO(cs) fix https://github.com/ugorji/go/issues/92#issuecomment-140410732
	//		runCodec(ts.Package, ts.OutputFile.AppendName("_codec").String(), ts.OutputFile.String())
	//	}
}
Example #20
0
func getImportPaths() []string {
	var paths utils.StringSlice

	var getPath = func(s string) string {
		ps, err := codegen.ExtractImportPath(s)
		codegen.LogFatal(err)
		return ps
	}

	for _, et := range codegen.ConfigEntityType {
		paths.Append(
			getPath(et.EntityModel),
			getPath(et.AttributeModel),
			getPath(et.EntityTable),
			getPath(et.IncrementModel),
			getPath(et.AdditionalAttributeTable),
			getPath(et.EntityAttributeCollection),
		)
	}
	return paths.Unique().ToString()
}
Example #21
0
func generateStructures(tStruct *codegen.TableToStruct, db *sql.DB, dbrConn *dbr.Connection) {
	tplData := &dataContainer{
		Tables:  make([]map[string]interface{}, 0, 200),
		Package: tStruct.Package,
		Tick:    "`",
	}

	tables, err := codegen.GetTables(db, codegen.ReplaceTablePrefix(tStruct.SQLQuery))
	codegen.LogFatal(err)

	if len(tStruct.EntityTypeCodes) > 0 && tStruct.EntityTypeCodes[0] != "" {
		tplData.TypeCodeValueTables, err = codegen.GetEavValueTables(dbrConn, tStruct.EntityTypeCodes)
		codegen.LogFatal(err)

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

	for _, table := range tables {

		columns, err := codegen.GetColumns(db, table)
		codegen.LogFatal(err)
		codegen.LogFatal(columns.MapSQLToGoDBRType())
		var name = table
		if mappedName, ok := codegen.TableMapMagento1To2[strings.Replace(table, codegen.TablePrefix, "", 1)]; ok {
			name = mappedName
		}
		tplData.Tables = append(tplData.Tables, map[string]interface{}{
			"name":    name,
			"table":   table,
			"columns": columns,
		})
	}

	formatted, err := codegen.GenerateCode(tStruct.Package, tplCode, tplData, nil)
	if err != nil {
		fmt.Printf("\n%s\n", formatted)
		codegen.LogFatal(err)
	}

	codegen.LogFatal(ioutil.WriteFile(tStruct.OutputFile, formatted, 0600))
}
Example #22
0
func attrGenerateData(ctx *context) map[string]interface{} {
	websiteID := int64(0) // always 0 because we're building the base struct
	columns := getAttrColumns(ctx, websiteID)
	attributeCollection, err := codegen.LoadStringEntities(ctx.db, getAttrSelect(ctx, websiteID))
	codegen.LogFatal(err)

	pkg := getPackage(ctx.et)
	importPaths := codegen.PrepareForTemplate(columns, attributeCollection, codegen.ConfigAttributeModel, pkg)

	return map[string]interface{}{
		"AttrCol":        attributeCollection,
		"AttrPkg":        getAttrPkg(ctx.et),
		"AttrPkgImp":     codegen.ConfigMaterializationAttributes[ctx.et.EntityTypeCode].AttrPkgImp,
		"AttrStruct":     codegen.ConfigMaterializationAttributes[ctx.et.EntityTypeCode].AttrStruct,
		"FuncCollection": codegen.ConfigMaterializationAttributes[ctx.et.EntityTypeCode].FuncCollection,
		"FuncGetter":     codegen.ConfigMaterializationAttributes[ctx.et.EntityTypeCode].FuncGetter,
		"ImportPaths":    importPaths,
		"MyStruct":       codegen.ConfigMaterializationAttributes[ctx.et.EntityTypeCode].MyStruct,
		"Name":           getStructName(ctx, "attribute"),
		"PackageName":    pkg,
	}
}
Example #23
0
func getAttrColumns(ctx *context, websiteID int64) codegen.Columns {
	columns, err := codegen.SQLQueryToColumns(ctx.db, getAttrSelect(ctx, websiteID))
	codegen.LogFatal(err)
	codegen.LogFatal(columns.MapSQLToGoType(codegen.EavAttributeColumnNameToInterface))
	return columns
}