// Load SDB DB score data for territory ts.uid. func loadFromSQL(db *mysql.Client, ts *territoryScore) { query := "SELECT TScoreTotal,TScoreBalance,TScoreTime,name FROM avatars WHERE ID='" + fmt.Sprint(ts.uid) + "'" stmt, err := db.Prepare(query) if err != nil { log.Println(err) return } // Execute statement err = stmt.Execute() if err != nil { log.Println(err) return } var terrScore, terrScoreBalance float64 var terrScoreTimestamp uint32 var name string stmt.BindResult(&terrScore, &terrScoreBalance, &terrScoreTimestamp, &name) for { eof, err := stmt.Fetch() if err != nil { log.Println(err) return } if eof { break } } numChunks := countChunks(db, ts.uid) Initialize(ts.uid, terrScore, terrScoreBalance, terrScoreTimestamp, name, numChunks) }
// met à jour un compte en BD, sans les infos de gestion (comme le mdp) func (store *MysqlStore) UpdateTroll(db *mysql.Client, c *Compte) (err os.Error) { t := c.Troll if t == nil { fmt.Println("Compte sans données de troll") return } updateProfil := t.ProchainTour > 0 // on ne met pas toujours tout à jour sql := "update compte set" sql += " x=?, y=?, z=?" if updateProfil { sql += " ,pv_max=?, pv_actuels=?, fatigue=?, pa=?, vue=?, prochain_tour=?, duree_tour=?, mise_a_jour=?" } sql += " where id=?" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() if updateProfil { err = stmt.BindParams(t.X, t.Y, t.Z, t.PV_max, t.PV_actuels, t.Fatigue, t.PA, t.Vue, (t.ProchainTour / 1000), t.DureeTour, time.Seconds(), c.trollId) } else { err = stmt.BindParams(t.X, t.Y, t.Z, c.trollId) } if err != nil { return } err = stmt.Execute() return }
// stocke une action en BD (résultat de sort ou de frappe ou compétence, à l'exclusion des CDM) func (store *MysqlStore) InsertAction(db *mysql.Client, a *Action) (err error) { // on corrige if a.Degats > 0 && a.PV == 0 { a.PV = a.Degats } a.Type = AsciiToUTF8([]uint8(a.Type)) sql := "insert into action" sql += " (date_action, type_action, auteur, type_cible, num_cible, succes, degats, pv, esquive)" sql += " values ( ?, ?, ?, ?, ?, ?, ?, ?, ?)" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() succès := "non" if a.Succes { succès = "oui" } err = stmt.BindParams(a.Date, a.Type, a.Auteur, a.TypeCible, a.NumCible, succès, a.Degats, a.PV, a.Esquive) if err != nil { return } err = stmt.Execute() if err != nil { return } return }
// modifie un partage // est-ce qu'on pourrait faire ça en une seule requête ? func (store *MysqlStore) UpdatePartage(db *mysql.Client, troll uint, autreTroll uint, statut string) (err error) { sql := "update partage set statut_a=? where troll_a=? and troll_b=?" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(statut, troll, autreTroll) if err != nil { return } err = stmt.Execute() if err != nil { return } sql = "update partage set statut_b=? where troll_a=? and troll_b=?" stmt2, err := db.Prepare(sql) defer stmt.FreeResult() if err != nil { return } err = stmt2.BindParams(statut, autreTroll, troll) if err != nil { return } err = stmt2.Execute() return }
// lit un compte en base. Renvoie nil si le compte n'existe pas en base. // Sinon l'appelant est responsable de l'ouverture et de la fermeture de la connexion qu'il fournit func (store *MysqlStore) GetCompte(db *mysql.Client, trollId uint) (c *Compte, err os.Error) { if trollId == 0 { fmt.Println("GetCompte> trollId invalide") return } sql := "select statut, mdp_restreint, pv_max, pv_actuels, x, y, z, fatigue, pa, vue, prochain_tour, duree_tour, mise_a_jour" sql += " from compte where id=" + strconv.Uitoa(trollId) err = db.Query(sql) if err != nil { return } result, err := db.UseResult() if err != nil { return } defer result.Free() row := result.FetchRow() if row == nil { return } c = rowToCompte(trollId, row) return }
// renvoie la liste des trolls avec qui le troll passé a un partage actif func (store *MysqlStore) GetPartageurs(db *mysql.Client, trollId int) ([]int, error) { st := strconv.Itoa(trollId) sql := "select troll_a, troll_b from partage where (troll_a=" + st + " or troll_b=" + st + ") and statut_a='on' and statut_b='on'" err := db.Query(sql) if err != nil { return nil, err } result, err := db.UseResult() if err != nil { return nil, err } defer result.Free() amis := make([]int, 0, 5) for { row := result.FetchRow() if row == nil { break } r0 := fieldAsInt(row[0]) r1 := fieldAsInt(row[1]) if r0 == trollId { amis = append(amis, r1) } else { amis = append(amis, r0) } } return amis, nil }
// stocke une note en BD func (store *MysqlStore) SaveNote(db *mysql.Client, note *Note) error { if note.Id > 0 { // update // TODO utiliser comme clef l'id ET l'auteur, par sécurité (qu'on ne puisse pas effacer une note de quelqu'un d'autre) (pareil pour le delete) fmt.Println("update de note") } else { // insert sql := "insert into note (auteur, type_sujet, id_sujet, x_sujet, y_sujet, z_sujet, partage, date_changement, contenu, diplo)" sql += " values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" stmt, err := db.Prepare(sql) if err != nil { return err } defer stmt.FreeResult() seconds := time.Seconds() err = stmt.BindParams(note.Auteur, note.TypeSujet, note.IdSujet, note.XSujet, note.YSujet, note.ZSujet, note.Partage, seconds, note.Contenu, note.Diplo) if err != nil { fmt.Printf("Erreur stockage (in) note : %s\n", err.Error()) // FIXME l'erreur ne semble pas retransmise ??? return err } err = stmt.Execute() if err != nil { return err } } return nil }
// récupère toutes les infos de partage, acceptés ou non, impliquant un troll func (store *MysqlStore) GetAllPartages(db *mysql.Client, trollId uint) (partages []*Partage, err error) { sql := "select troll_a, troll_b, statut_a, statut_b from partage where troll_a=? or troll_b=?" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(trollId, trollId) if err != nil { return } err = stmt.Execute() if err != nil { return } r := new(Partage) stmt.BindResult(&r.TrollA, &r.TrollB, &r.StatutA, &r.StatutB) partages = make([]*Partage, 0, 10) for { eof, _err := stmt.Fetch() if _err != nil || eof { return partages, _err } p := &Partage{r.TrollA, r.TrollB, r.StatutA, r.StatutB} // on dirait qu'on ne peut pas dupliquer l'objet plus simplement partages = append(partages, p) } return }
func (store *MysqlStore) DeletePartage(db *mysql.Client, troll uint, autreTroll uint) (err error) { sql := "delete from partage where (troll_a=? and troll_b=?) or (troll_b=? and troll_a=?)" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(troll, autreTroll, troll, autreTroll) if err != nil { return } err = stmt.Execute() return }
func MySQLNewConnection(sock string, user string, password string, database string) (Connection, os.Error) { var err os.Error var db *mysql.Client db, err = mysql.DialUnix(sock, user, password, database) if err != nil { err = db.Close() return nil, err } conn := new(MySQL) conn.Database = database conn.db = db return conn, err }
// supprime la vue de trollID puis sauvegarde des observations reçues par SOAP de MH, observées juste maintenant par trollId func (store *MysqlStore) CleanAndSaveSoapItems(db *mysql.Client, trollId uint, items []*SoapItem) (err error) { seconds := time.Seconds() sql := "delete from observation where auteur=" + strconv.Uitoa(trollId) stmt, err := db.Prepare(sql) if err != nil { return } err = stmt.Execute() if err != nil { return } stmt.FreeResult() // nécessaire ? sql = "insert into observation" sql += " (auteur, num, date, type, nom, x, y, z)" sql += " values ( ?, ?, ?, ?, ?, ?, ?, ?)" stmt, err = db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() for _, i := range items { //~ fmt.Printf(" saving %+v\n", i) var t string if i.Type == "TROLL" { t = "troll" } else if i.Type == "MONSTRE" { t = "monstre" } else if i.Type == "LIEU" { t = "lieu" } else if i.Type == "TRESOR" { t = "tresor" } else { continue } err = stmt.BindParams(trollId, i.Numero, seconds, t, i.Nom, i.PositionX, i.PositionY, i.PositionN) if err != nil { return } err = stmt.Execute() } return }
func (store *MysqlStore) ObservationsAutour(db *mysql.Client, x int, y int, z int, dist int, trollId int, amis []int, withTresors bool) (observations []*Observation, err os.Error) { sql := "select auteur, num, date, type, nom, x, y, z from observation where" sql += " x>" + strconv.Itoa(x-dist-1) + " and x<" + strconv.Itoa(x+dist+1) sql += " and y>" + strconv.Itoa(y-dist-1) + " and y<" + strconv.Itoa(y+dist+1) sql += " and z>" + strconv.Itoa(z-dist/2-1) + " and z<" + strconv.Itoa(z+dist/2+1) if !withTresors { sql += " and type<>'tresor'" } sql += " and auteur in (" + strconv.Itoa(trollId) for _, id := range amis { sql += "," + strconv.Itoa(id) } sql += ") order by type, num, date desc" fmt.Println("SQL : ", sql) stmt, err := db.Prepare(sql) defer stmt.FreeResult() if err != nil { return } err = stmt.Execute() if err != nil { return } r := new(Observation) stmt.BindResult(&r.Auteur, &r.Num, &r.Date, &r.Type, &r.Nom, &r.X, &r.Y, &r.Z) observations = make([]*Observation, 0, 20) for { eof, err := stmt.Fetch() if err != nil || eof { return } //fmt.Printf("r : %+v\n", r) if len(observations) > 0 && r.Num == observations[len(observations)-1].Num { continue } o := &Observation{r.Auteur, r.Num, r.Type, r.Date, r.Nom, r.X, r.Y, r.Z} observations = append(observations, o) } return }
func saveToSQL(db *mysql.Client, ts *territoryScore) { ts.modified = false query := "UPDATE avatars SET TScoreTotal=?,TScoreBalance=?,TScoreTime=? WHERE ID='" + fmt.Sprint(ts.uid) + "'" stmt, err := db.Prepare(query) if err != nil { log.Println(err) return } stmt.BindParams(ts.Score, ts.ScoreBalance, ts.TimeStamp.Unix()) err = stmt.Execute() if err != nil { log.Println(err) return } }
func (store *MysqlStore) SearchObservations(db *mysql.Client, tok string, trollId int, amis []int) (observations []*Observation, err error) { sql := "select auteur, num, date, type, nom, x, y, z from observation where" if num, _ := strconv.Atoi(tok); num != 0 { sql += " num=" + tok } else { sql += " nom like '%" + tok + "%'" } sql += " and auteur in (" + strconv.Itoa(trollId) for _, id := range amis { sql += "," + strconv.Itoa(id) } sql += ") order by num, date desc limit 100" fmt.Println("SQL : ", sql) stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.Execute() if err != nil { return } r := new(Observation) stmt.BindResult(&r.Auteur, &r.Num, &r.Date, &r.Type, &r.Nom, &r.X, &r.Y, &r.Z) observations = make([]*Observation, 0, 20) for { eof, _err := stmt.Fetch() if _err != nil || eof { return observations, _err } if len(observations) > 0 && r.Num == observations[len(observations)-1].Num { // dédoublonnage continue } o := &Observation{r.Auteur, r.Num, r.Type, r.Date, r.Nom, r.X, r.Y, r.Z} observations = append(observations, o) } return }
// sauvegarde un nouveau partage (à l'état de proposition de a pour b) func (store *MysqlStore) InsertPartage(db *mysql.Client, trollA uint, trollB uint) (err error) { sql := "insert ignore into" sql += " partage (troll_a, troll_b)" sql += " values ( ?, ?)" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(trollA, trollB) if err != nil { return } err = stmt.Execute() return }
// pour : le troll qui demande // troll : celui dont le compte est incrémenté // si ok est true, alors il faut faire l'appel (on le compte) func (store *MysqlStore) CheckBeforeSoapCall(db *mysql.Client, pour uint, troll uint, cat string, limite int64) (ok bool, err error) { seconds := time.Seconds() // on commence par compter hier := seconds - 24*60*60 sql := "select count(*) from appel_soap where troll=? and type=? and date>?" stmt, err := db.Prepare(sql) if err != nil { return } err = stmt.BindParams(troll, cat, hier) if err != nil { return } err = stmt.Execute() if err != nil { return } var r int64 stmt.BindResult(&r) _, err = stmt.Fetch() stmt.FreeResult() if err != nil || r >= limite { return } // c'est bon, donc on va noter l'appel qui va suivre sql = "insert into appel_soap (troll, pour, date, type) values (?, ?, ?, ?)" stmt, err = db.Prepare(sql) if err != nil { return } err = stmt.BindParams(troll, pour, seconds, cat) if err != nil { return } defer stmt.FreeResult() err = stmt.Execute() ok = true return }
// met à jour les champs de gestion d'un compte en BD // L'appelant est responsable de l'ouverture et de la fermeture de la connexion. func (store *MysqlStore) UpdateInfosGestionCompte(db *mysql.Client, c *Compte) (err os.Error) { sql := "update compte set" sql += " statut=?," sql += " mdp_restreint=?" sql += " where id=?" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(c.statut, c.mdpRestreint, c.trollId) if err != nil { return } err = stmt.Execute() return }
// un résultat sans auteur (0) ni dateCdm (valeur 0) signifie qu'on n'a pas la réponse à la question func (store *MysqlStore) GetBlessure(db *mysql.Client, numMonstre uint, trollId int, amis []int) (blessure uint, auteurCDM int, dateCDM int64, err os.Error) { sql := "select blessure, author, date_adition from cdm where" sql += " num_monstre=" + strconv.Uitoa(numMonstre) + " and" sql += " author in (" + strconv.Itoa(trollId) for _, id := range amis { sql += "," + strconv.Itoa(id) } sql += ") order by date_adition desc limit 1" err = db.Query(sql) if err != nil { return } result, err := db.UseResult() if err != nil { return } row := result.FetchRow() db.FreeResult() if row == nil { return } blessure = fieldAsUint(row[0]) auteurCDM = fieldAsInt(row[1]) dateCDM = fieldAsInt64(row[2]) return }
func Authenticate(username string, passwordHash string, dbConn *mysql.Client) (reply *AuthenticationReply, err os.Error) { // Default return argument reply = NewAuthenticationReply(false, -1, "") // Escape input username = dbConn.Escape(username) password := dbConn.Escape(passwordHash) fmt.Printf("Authenticating user: '******'\n", username, password) err = dbConn.Query("SELECT * FROM users WHERE nick = '" + username + "' AND password = '******' limit 1") if err != nil { return } result, err := dbConn.UseResult() defer dbConn.FreeResult() if err != nil { return } // Fetch the row row := result.FetchMap() // If we found it the client got the username and password right if row != nil { id := row["id"].(int64) nick := row["nick"].(string) reply = NewAuthenticationReply(true, id, nick) return } else { err = os.NewError("Wrong username or password.") } return }
// sauvegarde des observations reçues par SOAP de MH, observées juste maintenant par trollId func (store *MysqlStore) SaveSoapItems(db *mysql.Client, trollId uint, items []SoapItem) (err error) { seconds := time.Seconds() sql := "insert into observation" sql += " (auteur, num, date, type, nom, x, y, z)" sql += " values ( ?, ?, ?, ?, ?, ?, ?, ?)" sql += " on duplicate key update date=?, nom=?, x=?, y=?, z=?" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() for _, i := range items { var t string if i.Type == "TROLL" { t = "troll" } else if i.Type == "MONSTRE" { t = "monstre" } else if i.Type == "TRESOR" { t = "tresor" } else if i.Type == "LIEU" { t = "lieu" } else { continue } err = stmt.BindParams(trollId, i.Numero, seconds, t, i.Nom, i.PositionX, i.PositionY, i.PositionN, seconds, i.Nom, i.PositionX, i.PositionY, i.PositionN) if err != nil { return } err = stmt.Execute() } return }
func (store *MysqlStore) GetAllPartages_old(db *mysql.Client, trollId uint) (partages []*Partage, err error) { sql := "select troll_a, troll_b, statut_a, statut_b from partage where troll_a=" + strconv.Uitoa(trollId) + " or troll_b=" + strconv.Uitoa(trollId) err = db.Query(sql) if err != nil { return } result, err := db.UseResult() if err != nil { return } defer result.Free() partages = make([]*Partage, 0, 10) for { row := result.FetchRow() if row == nil { break } p := new(Partage) p.TrollA = fieldAsUint(row[0]) p.TrollB = fieldAsUint(row[1]) p.StatutA = fieldAsString(row[2]) p.StatutB = fieldAsString(row[3]) l := len(partages) if l == cap(partages) { newSlice := make([]*Partage, (l+1)*3/2) copy(newSlice, partages) partages = newSlice } partages = partages[0 : l+1] partages[l] = p } return }
// sauvegarde un nouveau compte. // L'appelant est responsable de l'ouverture et de la fermeture de la connexion. func (store *MysqlStore) InsertCompte(db *mysql.Client, c *Compte) (err os.Error) { sql := "insert into" sql += " compte (id, statut, mdp_restreint)" sql += " values ( ?, ?, ?)" stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.BindParams(c.trollId, c.statut, c.mdpRestreint) if err != nil { return } err = stmt.Execute() if err != nil { return } return }
// Count the number of chunks this player has func countChunks(db *mysql.Client, uid uint32) int { // Build a query for the given chunk coordinate as an argument query := fmt.Sprintf("SELECT * FROM chunkdata WHERE avatarID=%d", uid) err := db.Query(query) if err != nil { // Fatal error log.Println(err) return ConfigHandicapLimit } // Store the result result, err := db.StoreResult() if err != nil { log.Println(err) return ConfigHandicapLimit } numRows := result.RowCount() db.FreeResult() return int(numRows) }
// renvoie les actions, en incluant les résumés de CDM func (store *MysqlStore) GetActions(db *mysql.Client, typeCible string, numCible int, trollId int, amis []int) (actions []*Action, err error) { strnum := strconv.Itoa(numCible) //> d'abord les vraies "actions" sql := "select date_action, type_action, auteur, succes, degats, pv, esquive from action where type_cible='" + typeCible + "' and num_cible=" + strnum sql += " and auteur in (" + strconv.Itoa(trollId) for _, id := range amis { sql += "," + strconv.Itoa(id) } sql += ")" fmt.Println(sql) err = db.Query(sql) if err != nil { return } result, err := db.UseResult() if err != nil { return } actions = make([]*Action, 0, 10) for { row := result.FetchRow() fmt.Printf("row : %v\n", row) if row == nil { break } a := new(Action) a.Date = fieldAsInt64(row[0]) a.Type = fieldAsString(row[1]) a.Auteur = fieldAsInt(row[2]) a.TypeCible = typeCible a.NumCible = numCible if fieldAsString(row[3]) == "oui" { a.Succes = true } else { a.Succes = false } a.Degats = fieldAsInt(row[4]) a.PV = fieldAsInt(row[5]) a.Esquive = fieldAsInt(row[6]) actions = append(actions, a) } db.FreeResult() //> ensuite les cdm if typeCible != "monstre" { return } sql = "select date_adition, author , blessure from cdm where num_monstre=" + strnum sql += " and author in (" + strconv.Itoa(trollId) for _, id := range amis { sql += "," + strconv.Itoa(id) } sql += ")" fmt.Println(sql) err = db.Query(sql) if err != nil { return } result, err = db.UseResult() if err != nil { return } for { row := result.FetchRow() fmt.Printf("row : %v\n", row) if row == nil { break } a := new(Action) a.Date = fieldAsInt64(row[0]) a.Auteur = fieldAsInt(row[1]) a.PourcentageBlessure = fieldAsInt(row[2]) a.Type = "CDM" a.TypeCible = typeCible a.NumCible = numCible a.Succes = true actions = append(actions, a) } db.FreeResult() return }
/** * estime les caractéristiques du monstre. * Si l'id est fourni (i.e. pas 0) et si on a des cdm concernant ce monstre précis, on n'utilise que celles là [EN COURS] */ func (store *MysqlStore) ComputeMonsterStats(db *mysql.Client, completeName string, monsterId uint) (be *BestiaryExtract, err os.Error) { // On utilise des max pour les champs de type chaine. C'est sans doute trop lourd (à moins que MySQL ne mette en place un index // spécifique). L'objectif réel est de récupérer la chaine la plus longue. if monsterId != 0 { sql := "select count(*), count(distinct num_monstre)," sql += namaxmin("niveau") + ", " sql += namaxmin("points_de_vie") + ", " sql += "max(capacite_text), " sql += namaxmin("des_attaque") + ", " sql += namaxmin("des_esquive") + ", " sql += namaxmin("des_degats") + ", " sql += namaxmin("des_regeneration") + ", " sql += namaxmin("armure") + ", " sql += namaxmin("vue") + ", " sql += namaxmin("maitrise_magique") + ", " sql += namaxmin("resistance_magique") + ", " sql += " max(famille_text), " sql += " max(nombre_attaques), " sql += " max(vitesse_deplacement_text), " sql += " max(voir_le_cache_boolean), " sql += " max(attaque_a_distance_boolean), " sql += namaxmin("duree_tour") + ", " sql += " max(portee_du_pouvoir_text)" sql += " from cdm where nom_complet=" + toMysqlString(completeName) sql += " and num_monstre=" + strconv.Uitoa(monsterId) //fmt.Println("SQL :\n" + sql + "\n") err = db.Query(sql) if err != nil { return nil, err } result, err := db.UseResult() if err != nil { return nil, err } row := result.FetchRow() db.FreeResult() if row != nil { be = rowToBestiaryExtract(completeName, row) if be.NbCdm > 0 { be.PreciseMonster = true return be, nil } } } sql := "select count(*), count(distinct num_monstre)," sql += namaxmin("niveau") + ", " // namaxmin car le niveau d'un monstre est fixe pour un nom complet donné sql += naminmax("points_de_vie") + ", " sql += "max(capacite_text), " sql += naminmax("des_attaque") + ", " sql += naminmax("des_esquive") + ", " sql += naminmax("des_degats") + ", " sql += naminmax("des_regeneration") + ", " sql += naminmax("armure") + ", " sql += naminmax("vue") + ", " sql += naminmax("maitrise_magique") + ", " sql += naminmax("resistance_magique") + ", " sql += " max(famille_text), " sql += " max(nombre_attaques), " sql += " max(vitesse_deplacement_text), " sql += " max(voir_le_cache_boolean), " sql += " max(attaque_a_distance_boolean), " sql += naminmax("duree_tour") + ", " sql += " max(portee_du_pouvoir_text)" sql += " from cdm where nom_complet=" + toMysqlString(completeName) //fmt.Println(sql) err = db.Query(sql) if err != nil { return nil, err } result, err := db.UseResult() if err != nil { return nil, err } row := result.FetchRow() db.FreeResult() if row == nil { //fmt.Println("ComputeMonsterStats : no result") return nil, nil } be = rowToBestiaryExtract(completeName, row) be.PreciseMonster = false return be, nil }
func (store *MysqlStore) WriteCdms(db *mysql.Client, cdms []*CDM, author int, seconds int64) (nbWrittenCdms int, err os.Error) { inserted := 0 sql := "insert ignore into cdm (author, num_monstre, nom_complet, nom, age, " // En go on ne peut pas déclarer une chaine sur plusieurs lignes. J'espère que le compilo combine... sql += "sha1, date_adition, " sql += " niveau_min, niveau_max," sql += " points_de_vie_min, points_de_vie_max, " sql += " capacite_text," sql += " des_attaque_min, des_attaque_max," sql += " des_esquive_min, des_esquive_max," sql += " des_degats_min, des_degats_max," sql += " des_regeneration_min, des_regeneration_max," sql += " armure_min, armure_max," sql += " vue_min, vue_max," sql += " maitrise_magique_min, maitrise_magique_max," sql += " resistance_magique_min, resistance_magique_max," sql += " famille_text," sql += " nombre_attaques," sql += " vitesse_deplacement_text," sql += " voir_le_cache_boolean," sql += " attaque_a_distance_boolean," sql += " dla_text," sql += " duree_tour_min, duree_tour_max," sql += " chargement_text," sql += " bonus_malus_text," sql += " portee_du_pouvoir_text," sql += " blessure)" sql += " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " sql += " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," sql += " ?, ?, ?, ?, ?, ?, ?, ?, ?)" //fmt.Println("SQL: " + sql) stmt, err := db.Prepare(sql) if err != nil { return 0, err } defer stmt.Close() if seconds == 0 { seconds = time.Seconds() } for _, cdm := range cdms { err = stmt.BindParams( author, cdm.NumMonstre, cdm.NomComplet, cdm.Nom, cdm.TagAge, cdm.ComputeSHA1(), seconds, cdm.Niveau_min, cdm.Niveau_max, cdm.PointsDeVie_min, cdm.PointsDeVie_max, cdm.Capacite_text, cdm.DésAttaque_min, cdm.DésAttaque_max, cdm.DésEsquive_min, cdm.DésEsquive_max, cdm.DésDégâts_min, cdm.DésDégâts_max, cdm.DésRégénération_min, cdm.DésRégénération_max, cdm.Armure_min, cdm.Armure_max, cdm.Vue_min, cdm.Vue_max, cdm.MaitriseMagique_min, cdm.MaitriseMagique_max, cdm.RésistanceMagique_min, cdm.RésistanceMagique_max, cdm.Famille_text, cdm.NombreDAttaques, cdm.VitesseDeDéplacement_text, uint8(cdm.VoirLeCaché_boolean), uint8(cdm.AttaqueADistance_boolean), cdm.DLA_text, cdm.DuréeTour_min, cdm.DuréeTour_max, cdm.Chargement_text, cdm.BonusMalus_text, cdm.PortéeDuPouvoir_text, cdm.Blessure) if err != nil { return inserted, err } err = stmt.Execute() if err != nil { return inserted, err } inserted += int(stmt.AffectedRows) } return inserted, nil }
// les paramètres passés sont des filtres optionnels // TODO ajouter filtres position func (store *MysqlStore) GetNotes(db *mysql.Client, typeSujet string, idSujet int, asker int, amis []int, showOnlyFromThisAuthor bool) (notes []*Note) { sql := "select id, auteur, type_sujet, id_sujet, x_sujet, y_sujet, z_sujet, partage, date_changement, contenu, diplo" + " from note " hasWhere := false if typeSujet != "" { sql += " where type_sujet='" + typeSujet + "'" // TODO vérifier le type avant... hasWhere = true } if idSujet != 0 { if hasWhere { sql += " and" } else { sql += " where" } sql += " id_sujet=" + strconv.Itoa(idSujet) hasWhere = true } if showOnlyFromThisAuthor { if hasWhere { sql += " and" } else { sql += " where" } sql += " auteur=" + strconv.Itoa(asker) } else { if hasWhere { sql += " and" } else { sql += " where" } sql += " (auteur=" + strconv.Itoa(asker) sql += " or (auteur in (" for i, id := range amis { if i > 0 { sql += "," } sql += strconv.Itoa(id) } sql += ") and partage>0) or partage>1)" } fmt.Printf("SQL : %s\n", sql) stmt, err := db.Prepare(sql) if err != nil { return } defer stmt.FreeResult() err = stmt.Execute() if err != nil { return } r := new(Note) stmt.BindResult(&r.Id, &r.Auteur, &r.TypeSujet, &r.IdSujet, &r.XSujet, &r.YSujet, &r.ZSujet, &r.Partage, &r.Date, &r.Contenu, &r.Diplo) notes = make([]*Note, 0, 20) for { eof, err := stmt.Fetch() if err != nil || eof { return } note := &Note{r.Id, r.Auteur, r.TypeSujet, r.IdSujet, r.XSujet, r.YSujet, r.ZSujet, r.Partage, r.Date, r.Contenu, r.Diplo} notes = append(notes, note) } return }