func hasError(err error, sql string) bool { if err != nil { switch err := err.(type) { case *mysql.MySQLError: if err.Number == NoSuchTable { return true } util.CheckErrFatal(err, sql) default: util.CheckErrFatal(err, sql) } } return false }
func Connect(driver, connection, prefix string, verbose bool) Database { db, err := sql.Open(driver, connection+parameters) util.CheckErrFatal(err, "Opening", connection) //db.SetMaxIdleConns(30) database := &gorp.DbMap{Db: db, Dialect: chooseDialect(driver)} controlTrace(verbose, database) return Database{db, database, prefix} }
func writeFile(fileName string, node *model.JoinedNodeDataBody, alias string, tags []string, menus []*model.JoinedMenu, emvideos []model.Emvideo) { file, err := os.Create(fileName) util.CheckErrFatal(err, "create", fileName) w := bufio.NewWriter(file) writeFrontMatter(w, node, alias, tags, menus) writeContent(w, node, emvideos) w.Flush() file.Close() }
func (db Database) JoinedNodeFields(offset, count int) []*JoinedNodeDataBody { sql := `select n.Nid, n.Vid, n.Type, n.Title, n.status as Published, n.Created, n.Changed, n.Comment, n.Promote, n.Sticky, nr.Body as BodyValue, nr.Teaser as BodySummary, nr.Format as BodyFormat from %snode n inner join %snode_revisions nr on n.nid = nr.nid and n.vid = nr.vid limit %d,%d` s2 := fmt.Sprintf(sql, db.Prefix, db.Prefix, offset, count) list, err := db.DbMap.Select(JoinedNodeDataBody{}, s2) util.CheckErrFatal(err, s2) return copyOutJoinedNodeDataBody(list) }
func (db Database) JoinedTaxonomyTerms(nid int32) []*JoinedTaxonomyTerm { sql := `select idx.Nid, t.Name, v.Name as Vocab from %sterm_node as idx inner join %sterm_data as t on idx.tid = t.tid join %svocabulary as v on t.vid = v.vid where idx.Nid = ?` s2 := fmt.Sprintf(sql, db.Prefix, db.Prefix, db.Prefix) list, err := db.DbMap.Select(JoinedTaxonomyTerm{}, s2, nid) util.CheckErrFatal(err, s2) return copyOutTaxonomyTerms(list) }
func (db Database) MenusForMlid(mlid int32) []*JoinedMenu { sql := `select menu_name as MenuName, mlid, plid, link_path as LinkPath, link_title as LinkTitle, module, external, has_children as HasChildren, expanded, weight, depth as TreeDepth, customized from %smenu_links where hidden = 0 and mlid = ?` s2 := fmt.Sprintf(sql, db.Prefix) list, err := db.DbMap.Select(Menu{}, s2, mlid) util.CheckErrFatal(err, s2) return convertMenu(copyOutMenu(list)) }
func (db Database) JoinedMenusForPath(path string) []*JoinedMenu { sql := `select c.menu_name as MenuName, c.title, m.mlid, m.plid, m.link_path as LinkPath, m.link_title as LinkTitle, m.module, m.external, m.has_children as HasChildren, m.expanded, m.weight, m.depth as TreeDepth, m.customized from %smenu_links as m join %smenu_custom as c on m.menu_name = c.menu_name where m.hidden = 0 and m.link_path = ?` s2 := fmt.Sprintf(sql, db.Prefix, db.Prefix) list, err := db.DbMap.Select(JoinedMenu{}, s2, path) util.CheckErrFatal(err, s2) return copyOutJoinedMenu(list) }
func (db Database) GetUrlAlias(nid int32) string { sql := `select pid, src as Source, dst as Alias, language from %surl_alias where src = ?` s2 := fmt.Sprintf(sql, db.Prefix) source := fmt.Sprintf("node/%d", nid) list, err := db.DbMap.Select(UrlAlias{}, s2, source) util.CheckErrFatal(err, s2) if len(list) > 1 { util.Fatal("Expected only one alias for %s but got %d.\n%+v\n", source, len(list), list) } if len(list) == 1 { return list[0].(*UrlAlias).Alias } return source }
func processNode(node *model.JoinedNodeDataBody, alias string, terms []*model.JoinedTaxonomyTerm, menus []*model.JoinedMenu, emvideos []model.Emvideo) { fileName := fmt.Sprintf("content/%s.md", alias) dir := path.Dir(fileName) if *verbose { fmt.Printf("%s %s '%s' pub=%v\n", node.Type, alias, node.Title, node.Published) fmt.Printf("mkdir %s\n", dir) // fmt.Printf("%+v\n", node) } err := os.MkdirAll(dir, os.FileMode(0755)) util.CheckErrFatal(err, "mkdir", dir) tags := flattenTaxonomies(terms) writeFile(fileName, node, alias, tags, menus, emvideos) }
func (db Database) AllMenus() []*MenuCustom { sql := "select * from " + db.Prefix + "menu_custom" list, err := db.DbMap.Select(MenuCustom{}, sql) util.CheckErrFatal(err, sql) return copyOutMenuCustoms(list) }
func AllNodes(dbMap *gorp.DbMap, prefix string) []*Node { sql := "select nid,vid,type,language,title,uid,status,created,changed,comment,promote,sticky,tnid,translate from " + prefix + "node" list, err := dbMap.Select(Node{}, sql) util.CheckErrFatal(err, sql) return copyOutNode(list) }
func (db Database) AllNodeTypes() []*NodeType { sql := "select type, name, module from " + db.Prefix + "node_type" list, err := db.DbMap.Select(NodeType{}, sql) util.CheckErrFatal(err, sql) return copyOutNodeType(list) }
func (db Database) AllVocabularies() []*Vocabulary { sql := "select vid,name from " + db.Prefix + "vocabulary" list, err := db.DbMap.Select(Vocabulary{}, sql) util.CheckErrFatal(err, sql) return copyOutVocabularies(list) }
func (db Database) CCKDataForNode(node *JoinedNodeDataBody, fields []*CCKFieldType) (map[CCKField]interface{}, error) { results := make(map[CCKField]interface{}) var err error selectFields := make([]CCKField, 0, 100) _sql := "SELECT " first := true for _, cft := range fields { fmt.Printf("looping through dbcolumns for %s\n", cft.Name) for k, v := range cft.DBColumns { fmt.Printf("%#v = %#v\n", k, v) key := k.(string) dbColumn := v.(map[interface{}]interface{}) typ, ok := dbColumn["type"] if ok { cckField := CCKField{cft.Name, key, typ.(string)} if !first { _sql = _sql + ", " } _sql = _sql + cft.Name + "_" + key selectFields = append(selectFields, cckField) first = false } } } if first { return results, nil } _sql += " FROM %scontent_type_%s WHERE vid = %d and nid = %d" query := fmt.Sprintf(_sql, db.Prefix, node.Type, node.Vid, node.Nid) rows, err := db.Db.Query(query) util.CheckErrFatal(err, "Selecting CCK field values for node.", node.Nid) defer rows.Close() columnNames, err := rows.Columns() if err != nil { util.Fatal("Error getting column names: %v", err) // or whatever error handling is appropriate } if len(columnNames) != len(selectFields) { util.Fatal("column names length and select fields length do not match!") } columns := make([]interface{}, len(columnNames)) columnPointers := make([]interface{}, len(columnNames)) for i := 0; i < len(columnNames); i++ { columnPointers[i] = &columns[i] } if rows.Next() { if err := rows.Scan(columnPointers...); err != nil { util.Fatal("Error reading a row: %v", err) } for i, colName := range selectFields { switch colName.Type { case "text", "varchar": switch cv := columns[i].(type) { case []byte: results[colName] = string(cv) default: if cv != nil { results[colName] = cv.(string) } } default: results[colName] = columns[i] } } } return results, nil }
func main() { flag.Parse() if *version { fmt.Fprintf(os.Stderr, "Version 0.1\n") os.Exit(0) } if *dbName == "" { flag.Usage() os.Exit(1) } if *user == "" { *user = *dbName } if *pass == "" { fmt.Printf("Password: "******"content") { fmt.Fprintln(os.Stderr, "There is no content directory here. Did you mean to try somewhere else?") os.Exit(2) } // username:password@protocol(address)/dbname?param=value db := model.Connect(*driver, *user+":"+*pass+"@tcp("+*host+")/"+*dbName, *prefix, *verbose) cckFieldTypes, err := db.CCKFields() if err != nil && *emvideoField != "" { util.Fatal("Unable to retrieve CCK Field metadata: %s", err.Error()) } allBookPagesAsMap := make(map[int32]*model.BookPage) //db.AllBookPagesAsMap() // fmt.Println("\nnode types:") // spew.Dump(db.AllNodeTypes()) // fmt.Println("\nbooks:") // spew.Dump(db.AllBooksAsMap()) // fmt.Println("\nbook pages:") // spew.Dump(allBookPagesAsMap) // fmt.Println("\nmenus:") // spew.Dump(db.AllMenus()) processVocabs(db) // for _, node := range model.AllNodes(db, *prefix) { // fmt.Printf("%v\n", node) // } offset := 0 nodes := db.JoinedNodeFields(offset, 10) for len(nodes) > 0 { for _, node := range nodes { alias := db.GetUrlAlias(node.Nid) terms := db.JoinedTaxonomyTerms(node.Nid) menus := db.JoinedMenusForPath(fmt.Sprintf("node/%d", node.Nid)) emvideos := make([]model.Emvideo, 0, 10) if *emvideoField != "" { cckData, err := db.CCKDataForNode(node, cckFieldTypes[node.Type]) if err != nil { util.Fatal("Unable to get CCK field data for node: %s", err.Error()) } for _, cckFieldType := range cckFieldTypes[node.Type] { if cckFieldType.Name == *emvideoField { video, err := model.EmvideoForNodeField(cckFieldType, cckData) if err == nil { emvideos = append(emvideos, *video) } } } } // hasMenuOrBook := false fmt.Printf("node/%d %s %s\n", node.Nid, alias, node.Title) if bookPage, exists := allBookPagesAsMap[node.Nid]; exists { // spew.Printf(" book %v\n", bookPage) if len(menus) == 0 { menus = db.MenusForMlid(bookPage.Mlid) } // hasMenuOrBook = true } if len(menus) > 0 { // spew.Printf(" menu %v\n", menus) // hasMenuOrBook = true } // if !hasMenuOrBook { // fmt.Printf(" --\n") // } processNode(node, alias, terms, menus, emvideos) } offset += len(nodes) nodes = db.JoinedNodeFields(offset, 10) } fmt.Printf("Total %d nodes.\n", offset) }