// UpdateLabelInfo updates project label information, returns false if the project does not exist. func UpdateLabelInfo(path string, label string, add bool) bool { // Connect to database. q := connDb() defer q.Close() info := new(hv.PkgInfo) err := q.WhereEqual("path", path).Find(info) if err != nil { return false } i := strings.Index(info.Labels, "$"+label+"|") switch { case i == -1 && add: // Add operation and does not contain. info.Labels += "$" + label + "|" _, err = q.Save(info) if err != nil { beego.Error("models.UpdateLabelInfo -> add:", path, err) } case i > -1 && !add: // Delete opetation and contains. info.Labels = strings.Replace(info.Labels, "$"+label+"|", "", 1) _, err = q.Save(info) if err != nil { beego.Error("models.UpdateLabelInfo -> delete:", path, err) } } return true }
func getPkgInfoWithQ(path, tag string, q *qbs.Qbs) (*hv.PkgInfo, error) { // Check path length to reduce connect times. if len(path) == 0 { return nil, errors.New("models.getPkgInfoWithQ -> Empty path as not found.") } pinfo := new(hv.PkgInfo) q.WhereEqual("import_path", path).Find(pinfo) proPath := utils.GetProjectPath(path) if utils.IsGoRepoPath(path) { proPath = "code.google.com/p/go" } beego.Trace("models.getPkgInfoWithQ -> proPath:", proPath) ptag := new(PkgTag) cond := qbs.NewCondition("path = ?", proPath).And("tag = ?", tag) err := q.Condition(cond).Find(ptag) if err != nil { pinfo.Ptag = "ptag" return pinfo, errors.New( fmt.Sprintf("models.getPkgInfoWithQ( %s:%s ) -> 'PkgTag': %s", path, tag, err)) } pinfo.Vcs = ptag.Vcs pinfo.Tags = ptag.Tags // Only 'PkgInfo' cannot prove that package exists, // we have to check 'PkgDecl' as well in case it was deleted by mistake. pdecl := new(PkgDecl) cond = qbs.NewCondition("pid = ?", pinfo.Id).And("tag = ?", tag) err = q.Condition(cond).Find(pdecl) if err != nil { // Basically, error means not found, so we set 'pinfo.PkgVer' to 0 // because server uses it to decide whether force update. pinfo.PkgVer = 0 pinfo.Ptag = "ptag" return pinfo, errors.New( fmt.Sprintf("models.getPkgInfoWithQ( %s:%s ) -> 'PkgDecl': %s", path, tag, err)) } docPath := path + utils.TagSuffix("-", tag) if !com.IsExist("." + utils.DocsJsPath + docPath + ".js") { pinfo.PkgVer = 0 pinfo.Ptag = "ptag" return pinfo, errors.New( fmt.Sprintf("models.getPkgInfoWithQ( %s:%s ) -> JS: File not found", path, tag)) } return pinfo, nil }
// 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 }
func updateImportInfo(q *qbs.Qbs, path string, pid, rank int, add bool) { spid := strconv.Itoa(pid) // Save package information. info := new(hv.PkgInfo) err := q.WhereEqual("import_path", path).Find(info) if err == nil { // Check if pid exists in this project. refPids := strings.Split(info.RefPids, "|") i := getRefIndex(refPids, spid) if add { // Add operation. if i == -1 { refPids = append(refPids, spid) i = len(refPids) - 1 } info.RefPids = strings.Join(refPids, "|") info.RefNum = len(refPids) if info.RefNum > 0 && strings.HasPrefix(info.RefPids, "|") { info.RefPids = info.RefPids[1:] info.RefNum-- } _, err = q.Save(info) if err != nil { beego.Error("models.updateImportInfo -> add:", path, err) } } else if i > -1 { // Delete operation refPids = append(refPids[:i], refPids[i+1:]...) info.RefPids = strings.Join(refPids, "|") info.RefNum = len(refPids) if info.RefNum > 0 && strings.HasPrefix(info.RefPids, "|") { info.RefPids = info.RefPids[1:] info.RefNum-- } _, err = q.Save(info) if err != nil { beego.Error("models.updateImportInfo -> delete:", path, err) } } return } if add { // Record imports. pimp := new(PkgImport) q.WhereEqual("path", path).Find(pimp) pimp.Path = path pimps := strings.Split(pimp.Imports, "|") i := getRefIndex(pimps, spid) if i == -1 { pimps = append(pimps, spid) pimp.Imports = strings.Join(pimps, "|") _, err = q.Save(pimp) if err != nil { beego.Error("models.updateImportInfo -> record import:", path, err) } } } }
// 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 }