// SaveProject saves package information, declaration and functions; // update import information. func SaveProject(pinfo *hv.PkgInfo, pdecl *PkgDecl, pfuncs []PkgFunc, imports []string) error { // Load package information(save after checked import information). info := &hv.PkgInfo{ImportPath: pinfo.ImportPath} has, err := x.Get(info) if err != nil { return errors.New( fmt.Sprintf("models.SaveProject( %s ) -> Get hv.PkgInfo: %s", pinfo.ImportPath, err)) } if has { pinfo.Id = info.Id } // ------------------------------ // Update imported information. // ------------------------------ isMaster := pdecl != nil && len(pdecl.Tag) == 0 if info.Id > 0 { // Current package. importeds := strings.Split(info.RefPids, "|") importPids := make([]string, 0, len(importeds)) for _, v := range importeds { pid, _ := strconv.ParseInt(v, 10, 64) if checkImport(info.ImportPath, pid) { importPids = append(importPids, v) } } pinfo.RefPids = strings.Join(importPids, "|") pinfo.RefNum = len(importPids) } if isMaster { pimp := &PkgImport{Path: pinfo.ImportPath} has, err := x.Get(pimp) if err != nil { return errors.New( fmt.Sprintf("models.SaveProject( %s ) -> Get PkgImport: %s", pinfo.ImportPath, err)) } if has { importPids := strings.Split(pinfo.RefPids, "|") pimps := strings.Split(pimp.Imports, "|") for _, v := range pimps { if len(v) == 0 { continue } pid, _ := strconv.ParseInt(v, 10, 64) if i := getRefIndex(importPids, v); i == -1 && checkImport(info.ImportPath, pid) { importPids = append(importPids, v) } } _, err := x.Id(pimp.Id).Delete(pimp) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Delete PkgImport:", err.Error()) } pinfo.RefPids = strings.Join(importPids, "|") pinfo.RefNum = len(importPids) if pinfo.RefNum > 0 && strings.HasPrefix(pinfo.RefPids, "|") { pinfo.RefPids = pinfo.RefPids[1:] pinfo.RefNum-- } } } else { pinfo.Ptag = info.Ptag } if has { _, err = x.Id(pinfo.Id).Update(pinfo) } else { _, err = x.Insert(pinfo) } if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Information2:", err) } // Don't need to check standard library and non-master projects. if imports != nil && isMaster && !utils.IsGoRepoPath(pinfo.ImportPath) { // Other packages. for _, v := range imports { if !utils.IsGoRepoPath(v) { // Only count non-standard library. updateImportInfo(v, int(pinfo.Id), int(pinfo.Rank), true) } } } // ------------- END ------------ // Save package declaration. decl := new(PkgDecl) if pdecl != nil { has, err := x.Where("pid = ?", pinfo.Id).And("tag = ?", pdecl.Tag).Get(decl) if err != nil { beego.Error("models.SaveProject(", pinfo.Id, pdecl.Tag, ") -> Get PkgDecl:", err.Error()) } if has { pdecl.Id = decl.Id } pdecl.Pid = pinfo.Id if has { _, err = x.Id(pdecl.Id).Update(pdecl) } else { _, err = x.Insert(pdecl) } if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Declaration:", err) } // ------------------------------ // Save package tag. // ------------------------------ proPath := utils.GetProjectPath(pinfo.ImportPath) if utils.IsGoRepoPath(pinfo.ImportPath) { proPath = "code.google.com/p/go" } pkgTag := &PkgTag{ Path: proPath, Tag: pdecl.Tag, } has, err = x.Get(pkgTag) if err != nil { beego.Error("models.SaveProject(", proPath, pdecl.Tag, ") -> Get PkgTag:", err) } if !has { pkgTag.Path = proPath pkgTag.Tag = pdecl.Tag } pkgTag.Vcs = pinfo.Vcs pkgTag.Tags = pinfo.Tags if has { _, err = x.Id(pkgTag.Id).Update(pkgTag) } else { _, err = x.Insert(pkgTag) } if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Save PkgTag:", err) } // ------------- END ------------ } // ------------------------------ // Save package functions. // ------------------------------ if pfuncs != nil { // Old package need to clean old data. if decl.Id > 0 { // Update all old functions' 'IsOle' to be true. type pkgFunc struct { IsOld bool } pfunc := &pkgFunc{IsOld: true} _, err = x.Where("pid = ?", pdecl.Id).UseBool().Update(pfunc) if err != nil { beego.Error("models.SaveProject(", pdecl.Id, ") -> Mark function old:", err) } } // Save new ones. for _, pf := range pfuncs { f := &PkgFunc{ Pid: pdecl.Id, Name: pf.Name, } has, err := x.Get(f) if err != nil { beego.Error("models.SaveProject(", pdecl.Id, ") -> Get PkgFunc:", err) continue } if has { pf.Id = f.Id } pf.Pid = pdecl.Id if has { _, err = x.Id(pf.Id).UseBool().Update(pf) } else { _, err = x.Insert(pf) } if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Update function(", pf.Name, "):", err) } } if decl.Id > 0 { // Delete old ones if exist. _, err := x.Where("pid = ?", pdecl.Id).And("is_old = ?", true).Delete(new(PkgFunc)) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Delete functions:", err) } } } // ------------- END ------------ return nil }
// SaveProject saves package information, declaration and functions; // update import information. func SaveProject(pinfo *hv.PkgInfo, pdecl *PkgDecl, pfuncs []*PkgFunc, imports []string) error { q := connDb() defer q.Close() // Load package information(save after checked import information). info := new(hv.PkgInfo) err := q.WhereEqual("import_path", pinfo.ImportPath).Find(info) if err == nil { pinfo.Id = info.Id } // ------------------------------ // Update imported information. // ------------------------------ isMaster := pdecl != nil && len(pdecl.Tag) == 0 if info.Id > 0 { // Current package. importeds := strings.Split(info.RefPids, "|") importPids := make([]string, 0, len(importeds)) for _, v := range importeds { pid, _ := strconv.ParseInt(v, 10, 64) if checkImport(q, info.ImportPath, pid) { importPids = append(importPids, v) } } pinfo.RefPids = strings.Join(importPids, "|") pinfo.RefNum = len(importPids) } if isMaster { pimp := new(PkgImport) err := q.WhereEqual("path", pinfo.ImportPath).Find(pimp) if err == nil { importPids := strings.Split(pinfo.RefPids, "|") pimps := strings.Split(pimp.Imports, "|") for _, v := range pimps { if len(v) == 0 { continue } pid, _ := strconv.ParseInt(v, 10, 64) if i := getRefIndex(importPids, v); i == -1 && checkImport(q, info.ImportPath, pid) { importPids = append(importPids, v) } } q.WhereEqual("id", pimp.Id).Delete(pimp) pinfo.RefPids = strings.Join(importPids, "|") pinfo.RefNum = len(importPids) if pinfo.RefNum > 0 && strings.HasPrefix(pinfo.RefPids, "|") { pinfo.RefPids = pinfo.RefPids[1:] pinfo.RefNum-- } } } else { pinfo.Ptag = info.Ptag } _, err = q.Save(pinfo) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Information2:", err) } // Don't need to check standard library and non-master projects. if imports != nil && isMaster && !utils.IsGoRepoPath(pinfo.ImportPath) { // Other packages. for _, v := range imports { if !utils.IsGoRepoPath(v) { // Only count non-standard library. updateImportInfo(q, v, int(pinfo.Id), int(pinfo.Rank), true) } } } // ------------- END ------------ // Save package declaration. decl := new(PkgDecl) if pdecl != nil { cond := qbs.NewCondition("pid = ?", pinfo.Id).And("tag = ?", pdecl.Tag) err = q.Condition(cond).Find(decl) if err == nil { pdecl.Id = decl.Id } pdecl.Pid = pinfo.Id _, err = q.Save(pdecl) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Declaration:", err) } // ------------------------------ // Save package tag. // ------------------------------ proPath := utils.GetProjectPath(pinfo.ImportPath) if utils.IsGoRepoPath(pinfo.ImportPath) { proPath = "code.google.com/p/go" } pkgTag := new(PkgTag) cond = qbs.NewCondition("path = ?", proPath).And("tag = ?", pdecl.Tag) err = q.Condition(cond).Find(pkgTag) if err != nil { pkgTag.Path = proPath pkgTag.Tag = pdecl.Tag } pkgTag.Vcs = pinfo.Vcs pkgTag.Tags = pinfo.Tags _, err = q.Save(pkgTag) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> PkgTag:", err) } // ------------- END ------------ } // ------------------------------ // Save package functions. // ------------------------------ if pfuncs != nil { // Old package need to clean old data. if decl.Id > 0 { // Update all old functions' 'IsOle' to be true. type pkgFunc struct { IsOld bool } pfunc := new(pkgFunc) pfunc.IsOld = true _, err = q.WhereEqual("pid", pdecl.Id).Update(pfunc) } // Save new ones. for _, pf := range pfuncs { f := new(PkgFunc) cond := qbs.NewCondition("pid = ?", pdecl.Id).And("name = ?", pf.Name) err = q.Condition(cond).Find(f) if err == nil { pf.Id = f.Id } pf.Pid = pdecl.Id _, err = q.Save(pf) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Update function(", pf.Name, "):", err) } } if decl.Id > 0 { // Delete old ones if exist. cond := qbs.NewCondition("pid = ?", pdecl.Id).And("is_old = ?", true) _, err = q.Condition(cond).Delete(new(PkgFunc)) if err != nil { beego.Error("models.SaveProject(", pinfo.ImportPath, ") -> Delete functions:", err) } } } // ------------- END ------------ return nil }