コード例 #1
0
ファイル: projects.go プロジェクト: juju2013/gowalker
// 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
}
コード例 #2
0
ファイル: projects.go プロジェクト: CharlesSong/gowalker
// 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
}