func (self *BundleManager) bundleStateGetNoLock(conn *sqlite.Conn, user string, bundle_id int) (BundleState, error) { if conn == nil { conn = self.conn } s, err := conn.Prepare("select state from bundles where bundles.user = ? and bundles.id = ?;") if err != nil { log.Printf("%v\n", err) return BundleState_Error, err } defer s.Finalize() err = s.Exec(user, bundle_id) if err != nil { log.Printf("%v\n", err) return BundleState_Error, err } for { if !s.Next() { break } var value int err = s.Scan(&value) if err != nil { log.Printf("%v\n", err) return BundleState_Error, err } return BundleState(value), nil } return BundleState_Error, errors.New("Unknown error.") }
func (self *BundleManager) bundleFileValidateNolock(conn *sqlite.Conn, user string, bundle_id int, file_id int) error { if conn == nil { conn = self.conn } //FIXME better way to encode username and column? s, err := conn.Prepare("select 1 from files, bundles where bundles.user = ? and bundles.id = ? and bundles.id = files.bundle_id and files.id = ?;") if err != nil { log.Printf("%v\n", err) return err } defer s.Finalize() err = s.Exec(user, bundle_id, file_id) if err != nil { log.Printf("%v\n", err) return err } for { if !s.Next() { break } var value int err = s.Scan(&value) if err != nil { log.Printf("%v\n", err) return err } if value == 1 { return nil } } return errors.New("The specified file is not owned by the user and bundle specified.") }
// Link a Server's channels together func populateChannelLinkInfo(server *Server, db *sqlite.Conn) (err os.Error) { stmt, err := db.Prepare("SELECT channel_id, link_id FROM channel_links WHERE server_id=?") if err != nil { return err } if err := stmt.Exec(server.Id); err != nil { return err } for stmt.Next() { var ( ChannelId int LinkId int ) if err := stmt.Scan(&ChannelId, &LinkId); err != nil { return err } channel, exists := server.Channels[ChannelId] if !exists { return os.NewError("Attempt to perform link operation on non-existant channel.") } other, exists := server.Channels[LinkId] if !exists { return os.NewError("Attempt to perform link operation on non-existant channel.") } server.LinkChannels(channel, other) } return nil }
// Populate channel with its ACLs by reading the SQLite databse. func populateChannelACLFromDatabase(server *Server, c *Channel, db *sqlite.Conn) os.Error { stmt, err := db.Prepare("SELECT user_id, group_name, apply_here, apply_sub, grantpriv, revokepriv FROM acl WHERE server_id=? AND channel_id=? ORDER BY priority") if err != nil { return err } if err := stmt.Exec(server.Id, c.Id); err != nil { return err } for stmt.Next() { var ( UserId string Group string ApplyHere bool ApplySub bool Allow int64 Deny int64 ) if err := stmt.Scan(&UserId, &Group, &ApplyHere, &ApplySub, &Allow, &Deny); err != nil { return err } acl := NewChannelACL(c) acl.ApplyHere = ApplyHere acl.ApplySubs = ApplySub if len(UserId) > 0 { acl.UserId, err = strconv.Atoi(UserId) if err != nil { return err } } else if len(Group) > 0 { acl.Group = Group } else { return os.NewError("Invalid ACL: Neither Group or UserId specified") } acl.Deny = Permission(Deny) acl.Allow = Permission(Allow) c.ACL = append(c.ACL, acl) } return nil }
func getRowCount(name string, conn *sqlite.Conn) (int, error) { stmt, err := conn.Prepare(fmt.Sprintf("select count(1) from %s;", name)) if err != nil { return -1, err } err = stmt.Exec() if err != nil { return -1, err } stmt.Next() var count int err = stmt.Scan(&count) if err != nil { return -1, err } stmt.Finalize() return count, nil }
// Add channel metadata (channel_info table from SQLite) by reading the SQLite database. func populateChannelInfoFromDatabase(server *Server, c *Channel, db *sqlite.Conn) os.Error { stmt, err := db.Prepare("SELECT value FROM channel_info WHERE server_id=? AND channel_id=? AND key=?") if err != nil { return err } // Fetch description if err := stmt.Exec(server.Id, c.Id, ChannelInfoDescription); err != nil { return err } for stmt.Next() { var description string err = stmt.Scan(&description) if err != nil { return err } key, err := globalBlobstore.Put([]byte(description)) if err != nil { return err } c.DescriptionBlob = key } if err := stmt.Reset(); err != nil { return err } // Fetch position if err := stmt.Exec(server.Id, c.Id, ChannelInfoPosition); err != nil { return err } for stmt.Next() { var pos int if err := stmt.Scan(&pos); err != nil { return err } c.Position = pos } return nil }
func (self *BundleManager) bundleFileGet(conn *sqlite.Conn, bundle *BundleMD, user string, bundle_id int, file_id int) (*BundleFileMD, error) { self.mutex.Lock() if self.shutdown { return nil, errors.New("BundleManager is shutdown.") } defer self.mutex.Unlock() if bundle != nil { bundle_id = bundle.id user = bundle.user } else { bundle = &BundleMD{id: bundle_id, user: user, bm: self} } s, err := conn.Prepare("select 1 from files, bundles where bundles.user = ? and bundles.id = ? and files.bundle_id = bundles.id and files.id = ?;") if err != nil { log.Printf("%v\n", err) return nil, err } defer s.Finalize() err = s.Exec(user, bundle_id, file_id) if err != nil { log.Printf("%v\n", err) return nil, err } for { if !s.Next() { break } var value int err = s.Scan(&value) if err != nil { log.Printf("%v\n", err) return nil, err } if value == 1 { if conn == self.conn { conn = nil } return &BundleFileMD{id: file_id, bundle: bundle, conn: conn}, nil } } return nil, errors.New("File Id " + strconv.Itoa(file_id) + " not found.") }
func (self *BundleManager) bundleFileIdAdd(conn *sqlite.Conn, user string, bundle_id int, pacifica_filename string, local_filename string) (int, error) { self.mutex.Lock() if self.shutdown { return -1, errors.New("BundleManager is shutdown.") } defer self.mutex.Unlock() sql := ` insert into files(bundle_id, local_filename, myemsl_filename) values( (select case when (state == ?) then ? else null end from bundles where user = ? and id = ?), ?, ? );` err := conn.Exec(sql, int(BundleState_Unsubmitted), bundle_id, user, bundle_id, local_filename, pacifica_filename) if err != nil { old_state, terr := self.bundleStateGetNoLock(conn, user, bundle_id) if terr != nil { log.Printf("%v\n", terr) return -1, err } if old_state != BundleState_Unsubmitted { return -1, errors.New("Can't add files to submitted bundle.") } s, terr := conn.Prepare("select id, local_filename from files where bundle_id = ? and myemsl_filename = ?;") if terr != nil { log.Printf("%v\n", terr) return -1, err } defer s.Finalize() terr = s.Exec(bundle_id, pacifica_filename) if terr != nil { log.Printf("%v\n", terr) return -1, err } for { if !s.Next() { break } var tid int var tlocal_filename string terr = s.Scan(&tid, &tlocal_filename) if terr != nil { log.Printf("%v\n", terr) return -1, err } if tlocal_filename == local_filename { return -1, errors.New(fmt.Sprintf("The file with the specified Server filename (%s) already exists in the bundle (%d)!", pacifica_filename, bundle_id)) } else { return -1, errors.New(fmt.Sprintf("The file with the specified Server filename (%s) already exists in the bundle (%d) but with a different local filename (%s != %s)!", pacifica_filename, bundle_id, local_filename, tlocal_filename)) } } log.Printf("%v\n", err) log.Printf("SQL: %s, %d, %d, %s, %d, %s, %s\n", sql, int(BundleState_Unsubmitted), bundle_id, user, bundle_id, local_filename, pacifica_filename) return -1, err } s, err := conn.Prepare("select last_insert_rowid();") if err != nil { log.Printf("%v\n", err) return -1, err } defer s.Finalize() for { if !s.Next() { break } var value int err = s.Scan(&value) if err != nil { log.Printf("%v\n", err) return -1, err } return value, nil } return -1, errors.New("Unknown error.") }
func populateUsers(server *Server, db *sqlite.Conn) (err os.Error) { // Populate the server with regular user data stmt, err := db.Prepare("SELECT user_id, name, pw, lastchannel, texture, strftime('%s', last_active) FROM users WHERE server_id=?") if err != nil { return } err = stmt.Exec(server.Id) if err != nil { return } for stmt.Next() { var ( UserId int64 UserName string SHA1Password string LastChannel int Texture []byte LastActive int64 ) err = stmt.Scan(&UserId, &UserName, &SHA1Password, &LastChannel, &Texture, &LastActive) if err != nil { continue } user, err := NewUser(uint32(UserId), UserName) if err != nil { return err } user.Password = "******" + SHA1Password key, err := globalBlobstore.Put(Texture) if err != nil { return err } user.TextureBlob = key user.LastActive = uint64(LastActive) user.LastChannelId = LastChannel server.Users[user.Id] = user } stmt, err = db.Prepare("SELECT key, value FROM user_info WHERE server_id=? AND user_id=?") if err != nil { return } // Populate users with any new-style UserInfo records for uid, user := range server.Users { err = stmt.Reset() if err != nil { return err } err = stmt.Exec(server.Id, uid) if err != nil { return err } for stmt.Next() { var ( Key int Value string ) err = stmt.Scan(&Key, &Value) if err != nil { return err } switch Key { case UserInfoEmail: user.Email = Value case UserInfoComment: key, err := globalBlobstore.Put([]byte(Value)) if err != nil { return err } user.CommentBlob = key case UserInfoHash: user.CertHash = Value case UserInfoLastActive: // not a kv-pair (trigger) case UserInfoPassword: // not a kv-pair case UserInfoName: // not a kv-pair } } } return }
// Populate the Server with Channels from the database. func populateChannelsFromDatabase(server *Server, db *sqlite.Conn, parentId int) os.Error { parent, exists := server.Channels[parentId] if !exists { return os.NewError("Non-existant parent") } stmt, err := db.Prepare("SELECT channel_id, name, inheritacl FROM channels WHERE server_id=? AND parent_id=?") if err != nil { return err } err = stmt.Exec(server.Id, parentId) if err != nil { return err } for stmt.Next() { var ( name string chanid int inherit bool ) err = stmt.Scan(&chanid, &name, &inherit) if err != nil { return err } c := server.NewChannel(chanid, name) c.InheritACL = inherit parent.AddChild(c) } // Add channel_info for _, c := range parent.children { err = populateChannelInfoFromDatabase(server, c, db) if err != nil { return err } } // Add ACLs for _, c := range parent.children { err = populateChannelACLFromDatabase(server, c, db) if err != nil { return err } } // Add groups for _, c := range parent.children { err = populateChannelGroupsFromDatabase(server, c, db) if err != nil { return err } } // Add subchannels for id, _ := range parent.children { err = populateChannelsFromDatabase(server, db, id) if err != nil { return err } } return nil }
// Populate channel with groups by reading the SQLite database. func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sqlite.Conn) os.Error { stmt, err := db.Prepare("SELECT group_id, name, inherit, inheritable FROM groups WHERE server_id=? AND channel_id=?") if err != nil { return err } if err := stmt.Exec(server.Id, c.Id); err != nil { return err } groups := make(map[int64]*Group) for stmt.Next() { var ( GroupId int64 Name string Inherit bool Inheritable bool ) if err := stmt.Scan(&GroupId, &Name, &Inherit, &Inheritable); err != nil { return err } g := NewGroup(c, Name) g.Inherit = Inherit g.Inheritable = Inheritable c.Groups[g.Name] = g groups[GroupId] = g } stmt, err = db.Prepare("SELECT user_id, addit FROM group_members WHERE server_id=? AND group_id=?") if err != nil { return err } for gid, grp := range groups { if err = stmt.Exec(server.Id, gid); err != nil { return err } for stmt.Next() { var ( UserId int64 Add bool ) if err := stmt.Scan(&UserId, &Add); err != nil { return err } if Add { grp.Add[int(UserId)] = true } else { grp.Remove[int(UserId)] = true } } } return nil }