Guest User

Untitled

a guest
Dec 10th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.61 KB | None | 0 0
  1. /*
  2. Un CRUD completo de GoLang y MySQL
  3. @author parzibyte
  4. */
  5. package main
  6.  
  7. import (
  8. "bufio" // Leer líneas incluso si tienen espacios
  9. "database/sql" // Interactuar con bases de datos
  10. "fmt" // Imprimir mensajes y esas cosas
  11. _ "github.com/go-sql-driver/mysql" // La librería que nos permite conectar a MySQL
  12. "os" // El búfer, para leer desde la terminal con os.Stdin
  13. )
  14.  
  15. type Contacto struct {
  16. Nombre, Direccion, CorreoElectronico string
  17. Id int
  18. }
  19.  
  20. func obtenerBaseDeDatos() (db *sql.DB, e error) {
  21. usuario := "root"
  22. pass := ""
  23. host := "tcp(127.0.0.1:3306)"
  24. nombreBaseDeDatos := "agenda"
  25. // Debe tener la forma usuario:contraseña@protocolo(host:puerto)/nombreBaseDeDatos
  26. db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@%s/%s", usuario, pass, host, nombreBaseDeDatos))
  27. if err != nil {
  28. return nil, err
  29. }
  30. return db, nil
  31. }
  32.  
  33. func main() {
  34. creditos := `==========================================================
  35. CRUD de MySQL y GO
  36.  
  37. __ __ __
  38. .-----.---.-.----.-----|__| |--.--.--| |_.-----.
  39. | _ | _ | _|-- __| | _ | | | _| -__|
  40. | __|___._|__| |_____|__|_____|___ |____|_____|
  41. |__| |_____|
  42. ==========================================================`
  43. fmt.Println(creditos)
  44. menu := `¿Qué deseas hacer?
  45. [1] -- Insertar
  46. [2] -- Mostrar
  47. [3] -- Actualizar
  48. [4] -- Eliminar
  49. [5] -- Salir
  50. -----> `
  51. var eleccion int
  52. var c Contacto
  53. for eleccion != 5 {
  54. fmt.Print(menu)
  55. fmt.Scanln(&eleccion)
  56. scanner := bufio.NewScanner(os.Stdin)
  57. switch eleccion {
  58. case 1:
  59. fmt.Println("Ingresa el nombre:")
  60. if scanner.Scan() {
  61. c.Nombre = scanner.Text()
  62. }
  63. fmt.Println("Ingresa la dirección:")
  64. if scanner.Scan() {
  65. c.Direccion = scanner.Text()
  66. }
  67. fmt.Println("Ingresa el correo electrónico:")
  68. if scanner.Scan() {
  69. c.CorreoElectronico = scanner.Text()
  70. }
  71. err := insertar(c)
  72. if err != nil {
  73. fmt.Printf("Error insertando: %v", err)
  74. } else {
  75. fmt.Println("Insertado correctamente")
  76. }
  77. case 2:
  78. contactos, err := obtenerContactos()
  79. if err != nil {
  80. fmt.Printf("Error obteniendo contactos: %v", err)
  81. } else {
  82. for _, contacto := range contactos {
  83. fmt.Println("====================")
  84. fmt.Printf("Id: %d\n", contacto.Id)
  85. fmt.Printf("Nombre: %s\n", contacto.Nombre)
  86. fmt.Printf("Dirección: %s\n", contacto.Direccion)
  87. fmt.Printf("E-mail: %s\n", contacto.CorreoElectronico)
  88. }
  89. }
  90. case 3:
  91. fmt.Println("Ingresa el id:")
  92. fmt.Scanln(&c.Id)
  93. fmt.Println("Ingresa el nuevo nombre:")
  94. if scanner.Scan() {
  95. c.Nombre = scanner.Text()
  96. }
  97. fmt.Println("Ingresa la nueva dirección:")
  98. if scanner.Scan() {
  99. c.Direccion = scanner.Text()
  100. }
  101. fmt.Println("Ingresa el nuevo correo electrónico:")
  102. if scanner.Scan() {
  103. c.CorreoElectronico = scanner.Text()
  104. }
  105. err := actualizar(c)
  106. if err != nil {
  107. fmt.Printf("Error actualizando: %v", err)
  108. } else {
  109. fmt.Println("Actualizado correctamente")
  110. }
  111. case 4:
  112. fmt.Println("Ingresa el ID del contacto que deseas eliminar:")
  113. fmt.Scanln(&c.Id)
  114. err := eliminar(c)
  115. if err != nil {
  116. fmt.Printf("Error eliminando: %v", err)
  117. } else {
  118. fmt.Println("Eliminado correctamente")
  119. }
  120. }
  121. }
  122. }
  123.  
  124. func eliminar(c Contacto) error {
  125. db, err := obtenerBaseDeDatos()
  126. if err != nil {
  127. return err
  128. }
  129. defer db.Close()
  130.  
  131. sentenciaPreparada, err := db.Prepare("DELETE FROM agenda WHERE id = ?")
  132. if err != nil {
  133. return err
  134. }
  135. defer sentenciaPreparada.Close()
  136.  
  137. _, err = sentenciaPreparada.Exec(c.Id)
  138. if err != nil {
  139. return err
  140. }
  141. return nil
  142. }
  143.  
  144. func insertar(c Contacto) (e error) {
  145. db, err := obtenerBaseDeDatos()
  146. if err != nil {
  147. return err
  148. }
  149. defer db.Close()
  150.  
  151. // Preparamos para prevenir inyecciones SQL
  152. sentenciaPreparada, err := db.Prepare("INSERT INTO agenda (nombre, direccion, correo_electronico) VALUES(?, ?, ?)")
  153. if err != nil {
  154. return err
  155. }
  156. defer sentenciaPreparada.Close()
  157. // Ejecutar sentencia, un valor por cada '?'
  158. _, err = sentenciaPreparada.Exec(c.Nombre, c.Direccion, c.CorreoElectronico)
  159. if err != nil {
  160. return err
  161. }
  162. return nil
  163. }
  164.  
  165. func obtenerContactos() ([]Contacto, error) {
  166. contactos := []Contacto{}
  167. db, err := obtenerBaseDeDatos()
  168. if err != nil {
  169. return nil, err
  170. }
  171. defer db.Close()
  172. filas, err := db.Query("SELECT id, nombre, direccion, correo_electronico FROM agenda")
  173.  
  174. if err != nil {
  175. return nil, err
  176. }
  177. // Si llegamos aquí, significa que no ocurrió ningún error
  178. defer filas.Close()
  179.  
  180. // Aquí vamos a "mapear" lo que traiga la consulta en el while de más abajo
  181. var c Contacto
  182.  
  183. // Recorrer todas las filas, en un "while"
  184. for filas.Next() {
  185. err = filas.Scan(&c.Id, &c.Nombre, &c.Direccion, &c.CorreoElectronico)
  186. // Al escanear puede haber un error
  187. if err != nil {
  188. return nil, err
  189. }
  190. // Y si no, entonces agregamos lo leído al arreglo
  191. contactos = append(contactos, c)
  192. }
  193. // Vacío o no, regresamos el arreglo de contactos
  194. return contactos, nil
  195. }
  196.  
  197. func actualizar(c Contacto) error {
  198. db, err := obtenerBaseDeDatos()
  199. if err != nil {
  200. return err
  201. }
  202. defer db.Close()
  203.  
  204. sentenciaPreparada, err := db.Prepare("UPDATE agenda SET nombre = ?, direccion = ?, correo_electronico = ? WHERE id = ?")
  205. if err != nil {
  206. return err
  207. }
  208. defer sentenciaPreparada.Close()
  209. // Pasar argumentos en el mismo orden que la consulta
  210. _, err = sentenciaPreparada.Exec(c.Nombre, c.Direccion, c.CorreoElectronico, c.Id)
  211. return err // Ya sea nil o sea un error, lo manejaremos desde donde hacemos la llamada
  212. }
Add Comment
Please, Sign In to add comment