func (proj *project) Collaborators() []*lcmUser { if proj.collaborators != nil { return proj.collaborators } proj.collaborators = make([]*lcmUser, 0) rows := csql.Query(db, ` SELECT userid FROM collaborator WHERE project_name = $1 AND project_owner = $2 `, proj.Name, proj.Owner.Id) csql.ForRow(rows, func(s csql.RowScanner) { var userid string csql.Scan(rows, &userid) if user := findUserByNo(userid); user == nil { log.Printf("Could not find collaborator %s for "+ "project '%s' owned by '%s'.", userid, proj.Name, proj.Owner.Id) } else { proj.collaborators = append(proj.collaborators, user) } }) sort.Sort(usersAlphabetical(proj.collaborators)) return proj.collaborators }
// Tables returns the names of all tables in the database sorted // alphabetically in ascending order. func (db *DB) Tables() (tables []string, err error) { defer csql.Safe(&err) var q string switch db.Driver { case "postgres": q = ` SELECT tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') ORDER BY tablename ASC ` case "sqlite3": q = ` SELECT tbl_name FROM sqlite_master WHERE type = 'table' ORDER BY tbl_name ASC ` default: return nil, ef("Unrecognized database driver: %s", db.Driver) } rows := csql.Query(db, q) csql.ForRow(rows, func(rs csql.RowScanner) { var table string csql.Scan(rs, &table) if table != "migration_version" { tables = append(tables, table) } }) return }
// Get retrieves the current password hash for the user given. func (s *Store) Get(id string) (hash []byte, err error) { defer csql.Safe(&err) r := s.QueryRow(` SELECT hash FROM `+SqlTableName+` WHERE id = $1 `, id) csql.Scan(r, &hash) return }
// tableSize returns a pretty string indicating the size in table. Row count // is always include, but the size on disk is only included if it's supported // by the database. // Note that 'name' is assumed to be SQL-safe. func tableSize(db *imdb.DB, name string) string { count := csql.Count(db, sf("SELECT COUNT(*) AS count FROM %s", name)) if db.Driver == "sqlite3" { return sf("%d rows", count) } var size string q := sf("SELECT pg_size_pretty(pg_relation_size('%s'))", name) csql.Scan(db.QueryRow(q), &size) return sf("%d rows (%s)", count, size) }
// readRow scans a row from the atom table into an atomMap. func (az *atomizer) readRow(scanner csql.RowScanner) { var id imdb.Atom var rawBytes sql.RawBytes csql.Scan(scanner, &id, &rawBytes) var hash [md5.Size]byte hashBytes := hash[:] copy(hashBytes, rawBytes) az.atoms[hash] = id az.nextId = id }
// databaseSize returns a pretty string indicating the size of the entire // database on disk. func databaseSize(db *imdb.DB, dsn string) string { if db.Driver == "sqlite3" { fi, err := os.Stat(dsn) csql.Panic(err) return prettyFileSize(fi.Size()) } var size string q := sf("SELECT pg_size_pretty(pg_database_size(current_database()))") csql.Scan(db.QueryRow(q), &size) return size }
// attrs uses reflection to automatically construct a list of simple attribute // rows from the database based on information in the attribute's struct. // This includes building the SELECT query and the slice itself. // // zero MUST be a pointer to a simple struct. A simple struct MUST ONLY contain // fields that can be encoded/decoded as declared by the 'database/sql' // package. Column names are the lowercase version of their struct field name // unless the 'imdb_name' struct tag is set, in which case, that name is used. // // extra is passed to the end of the query executed. Useful for specifying // ORDER BY or LIMIT clauses. func attrs( zero interface{}, db csql.Queryer, e Entity, tableName string, idColumn string, extra string, ) (v interface{}, err error) { defer csql.Safe(&err) rz := reflect.ValueOf(zero).Elem() tz := rz.Type() nfields := tz.NumField() columns := make([]string, nfields) for i := 0; i < nfields; i++ { f := tz.Field(i) column := f.Tag.Get("imdb_name") if len(column) == 0 { column = strings.ToLower(f.Name) } columns[i] = column } tattrs := reflect.SliceOf(tz) vattrs := reflect.MakeSlice(tattrs, 0, 10) v = vattrs.Interface() q := sf("SELECT %s FROM %s WHERE %s = $1 %s", strings.Join(columns, ", "), tableName, idColumn, extra) rs := csql.Query(db, q, e.Ident()) csql.ForRow(rs, func(s csql.RowScanner) { loadCols := make([]interface{}, nfields) for i := 0; i < nfields; i++ { loadCols[i] = reflect.New(tz.Field(i).Type).Interface() } csql.Scan(s, loadCols...) row := reflect.New(tz).Elem() for i := 0; i < nfields; i++ { row.Field(i).Set(reflect.ValueOf(loadCols[i]).Elem()) } vattrs = reflect.Append(vattrs, row) }) v = vattrs.Interface() // not sure if this is necessary. return }
// Results executes the parameters of the search and returns the results. func (s *Searcher) Results() (rs []Result, err error) { defer csql.Safe(&err) // Set the similarity threshold first. if s.db.IsFuzzyEnabled() { csql.Exec(s.db, "SELECT set_limit($1)", s.similarThreshold) } if s.subTvshow != nil { if err := s.subTvshow.choose(s, s.chooser); err != nil { return nil, err } } if s.subCredits != nil { if err := s.subCredits.choose(s, s.chooser); err != nil { return nil, err } } if s.subCast != nil { if err := s.subCast.choose(s, s.chooser); err != nil { return nil, err } } var rows *sql.Rows if len(s.name) == 0 { rows = csql.Query(s.db, s.sql()) } else { rows = csql.Query(s.db, s.sql(), strings.Join(s.name, " ")) } csql.ForRow(rows, func(scanner csql.RowScanner) { var r Result var ent string csql.Scan(scanner, &ent, &r.Id, &r.Name, &r.Year, &r.Similarity, &r.Attrs, &r.Rank.Votes, &r.Rank.Rank, &r.Credit.ActorId, &r.Credit.MediaId, &r.Credit.Character, &r.Credit.Position, &r.Credit.Attrs) r.Entity = imdb.Entities[ent] rs = append(rs, r) }) return }
func (user *lcmUser) projects() []*project { projs := make([]*project, 0) rows := csql.Query(db, ` SELECT name, created FROM project WHERE owner = $1 ORDER BY name ASC `, user.Id) csql.ForRow(rows, func(s csql.RowScanner) { proj := &project{Owner: user} csql.Scan(rows, &proj.Name, &proj.Added) proj.Display = nameToDisplay(proj.Name) projs = append(projs, proj) }) return projs }