main.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strings"
  8. "time"
  9. "code.osinet.fr/fgm/entdemo/ent"
  10. "code.osinet.fr/fgm/entdemo/ent/car"
  11. "code.osinet.fr/fgm/entdemo/ent/group"
  12. "code.osinet.fr/fgm/entdemo/ent/user"
  13. _ "github.com/mattn/go-sqlite3"
  14. )
  15. func CreateUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
  16. u, err := client.User.
  17. Create().
  18. SetAge(30).
  19. SetName("a8m").
  20. Save(ctx)
  21. if err != nil {
  22. return nil, fmt.Errorf("failed creating user: %w", err)
  23. }
  24. log.Println("user was created: ", u)
  25. return u, nil
  26. }
  27. func QueryUser(ctx context.Context, client *ent.Client) (*ent.User, error) {
  28. const name = "a8m"
  29. u, err := client.User.
  30. Query().
  31. Where(user.NameEQ(name)).
  32. // "Only" fails if no user found or more than 1 user returned.
  33. Only(ctx)
  34. if err != nil {
  35. return nil, fmt.Errorf("failed querying user %s: %w", name, err)
  36. }
  37. log.Println("user returned: ", u)
  38. return u, nil
  39. }
  40. func CreateCars(ctx context.Context, client *ent.Client) (*ent.User, error) {
  41. var err error
  42. name := "tesla"
  43. tesla, err := client.Car.
  44. Create().
  45. SetModel(name).
  46. SetRegisteredAt(time.Now()).
  47. Save(ctx)
  48. if err != nil {
  49. return nil, fmt.Errorf("failed creating %s car: %v", name, err)
  50. }
  51. log.Println("car was created: ", tesla)
  52. name = "ford"
  53. ford, err := client.Car.
  54. Create().
  55. SetModel(name).
  56. SetRegisteredAt(time.Now()).
  57. Save(ctx)
  58. if err != nil {
  59. return nil, fmt.Errorf("failed creating %s car: %v", name, err)
  60. }
  61. log.Println("car was created: ", ford)
  62. u, err := QueryUser(ctx, client)
  63. if err != nil {
  64. return nil, fmt.Errorf("failed looking for user: %w", err)
  65. }
  66. u.Update().
  67. AddCars(tesla, ford).
  68. Save(ctx)
  69. if err != nil {
  70. return nil, fmt.Errorf("failed adding cards to user: %w", err)
  71. }
  72. return u, nil
  73. }
  74. func QueryCars(ctx context.Context, user *ent.User) error {
  75. cars, err := user.QueryCars().
  76. All(ctx)
  77. if err != nil {
  78. return fmt.Errorf("failed querying user %s cars: %w", user.Name, err)
  79. }
  80. log.Println("returned all cars: ", cars)
  81. ford, err := user.QueryCars().
  82. Where(car.ModelEQ("ford")).
  83. Only(ctx)
  84. if err != nil {
  85. return fmt.Errorf("failed searching for ford cars: %w", err)
  86. }
  87. log.Println("filtered cars: ", ford)
  88. return nil
  89. }
  90. func QueryCarUsers(ctx context.Context, u *ent.User) error {
  91. cars, err := u.QueryCars().All(ctx)
  92. if err != nil {
  93. return fmt.Errorf("failed querying user %s cars: %w", u.Name, err)
  94. }
  95. log.Println("returned all cars: ", cars)
  96. // query the inverse edge
  97. for _, car := range cars {
  98. owner, err := car.QueryOwner().Only(ctx)
  99. if err != nil {
  100. return fmt.Errorf("failed querying cat %s owner: %v", car.Model, err)
  101. }
  102. log.Printf("card %s owner: %q\n", car.Model, owner.Name)
  103. }
  104. return nil
  105. }
  106. func Open() (*ent.Client, error) {
  107. const db = "ent.db"
  108. err := os.Remove(db)
  109. if err != nil {
  110. pathErr, ok := err.(*os.PathError)
  111. if !ok {
  112. log.Fatalf("os.Remove returned a non-PathError: %w", err)
  113. }
  114. log.Printf("Error removing database: %s", pathErr.Error())
  115. }
  116. // Running client.Schema.Create will panic is DB exists already.
  117. client, err := ent.Open("sqlite3", strings.Join([]string{
  118. "file:",
  119. db,
  120. "?mode=rwc&cache=shared&_fk=1",
  121. },
  122. "",
  123. ))
  124. // client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
  125. return client, err
  126. }
  127. func BasicDemo(ctx context.Context, client *ent.Client) {
  128. u, err := CreateUser(ctx, client)
  129. if err != nil {
  130. panic(err)
  131. }
  132. _, err = QueryUser(ctx, client)
  133. if err != nil {
  134. panic(err)
  135. }
  136. _, err = CreateCars(ctx, client)
  137. if err != nil {
  138. panic(err)
  139. }
  140. err = QueryCars(ctx, u)
  141. if err != nil {
  142. panic(err)
  143. }
  144. err = QueryCarUsers(ctx, u)
  145. if err != nil {
  146. panic(err)
  147. }
  148. }
  149. func CreateGraph(ctx context.Context, client *ent.Client) error {
  150. ariel, err := client.User.
  151. Create().
  152. SetAge(30).
  153. SetName("ariel").
  154. Save(ctx)
  155. if err != nil {
  156. return err
  157. }
  158. neta, err := client.User.
  159. Create().
  160. SetAge(28).
  161. SetName("neta").
  162. Save(ctx)
  163. if err != nil {
  164. return err
  165. }
  166. // then, create the cars, and attach them to the users in the creation.
  167. _, err = client.Car.
  168. Create().
  169. SetModel("tesla").
  170. SetRegisteredAt(time.Now()). // ignore the time in the graph.
  171. SetOwner(ariel). // attach this graph to Ariel.
  172. Save(ctx)
  173. if err != nil {
  174. return err
  175. }
  176. _, err = client.Car.
  177. Create().
  178. SetModel("mazda").
  179. SetRegisteredAt(time.Now()). // ignore the time in the graph.
  180. SetOwner(ariel). // attach this graph to Ariel.
  181. Save(ctx)
  182. if err != nil {
  183. return err
  184. }
  185. _, err = client.Car.
  186. Create().
  187. SetModel("ford").
  188. SetRegisteredAt(time.Now()).
  189. SetOwner(neta).
  190. Save(ctx)
  191. if err != nil {
  192. return err
  193. }
  194. // create the groups, and add their users in the creation.
  195. _, err = client.Group.
  196. Create().
  197. SetName("GitLab").
  198. AddUsers(neta, ariel).
  199. Save(ctx)
  200. if err != nil {
  201. return err
  202. }
  203. _, err = client.Group.
  204. Create().
  205. SetName("GitHub").
  206. AddUsers(ariel).
  207. Save(ctx)
  208. if err != nil {
  209. return err
  210. }
  211. log.Println("The graph was created successfully")
  212. return nil
  213. }
  214. func QueryGithub(ctx context.Context, client *ent.Client) error {
  215. const name = "GitHub"
  216. cars, err := client.Group.
  217. Query().
  218. Where(group.Name(name)). // (Group(Name=GitHub),)
  219. QueryUsers(). // (User(Name=Ariel, Age=30),)
  220. QueryCars(). // (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
  221. All(ctx)
  222. if err != nil {
  223. return fmt.Errorf("failed getting %s cars: %w", name, err)
  224. }
  225. log.Println("cars returned: ", cars)
  226. // Output: (Car(Model=tesla, RegisteredAt=<Time>), Car(Model=mazda, RegisteredAt=<Time>),)
  227. return nil
  228. }
  229. // Get the cars of the users of all users in Ariel groups, except for the Mazda.
  230. func QueryAriel(ctx context.Context, client *ent.Client) error {
  231. const name = "ariel"
  232. // First get user ariel
  233. ariel := client.User.
  234. Query().
  235. Where(
  236. user.HasCars(), // Useless ?
  237. user.Name(name),
  238. ).
  239. OnlyX(ctx)
  240. cars, err := ariel.
  241. QueryGroups(). // Get Ariel's groups
  242. QueryUsers(). // Get the users in those groups
  243. QueryCars(). // Get the cars of the users in those groups
  244. Where(
  245. car.Not(
  246. car.ModelEQ("mazda"),
  247. ),
  248. ).
  249. All(ctx)
  250. if err != nil {
  251. return fmt.Errorf("failed getting %s cars: %w", name, err)
  252. }
  253. log.Println("cars returned: ", cars)
  254. // Output: (Car(Model=tesla, RegisteredAt=<Time>), Car(Model=ford, RegisteredAt=<Time>),)
  255. return nil
  256. }
  257. func QueryGroupsWithUsers(ctx context.Context, client *ent.Client) error {
  258. groups, err := client.Group.
  259. Query().
  260. Where(
  261. group.HasUsers(),
  262. ).
  263. All(ctx)
  264. if err != nil {
  265. return fmt.Errorf("failed gettings groups with users: %w", err)
  266. }
  267. log.Println("groups with users: ", groups)
  268. return nil
  269. }
  270. func main() {
  271. client, err := Open()
  272. if err != nil {
  273. log.Fatalf("failed opening connection to sqlite: %v", err)
  274. }
  275. defer client.Close()
  276. // Run the auto-migration tool.
  277. if err := client.Schema.Create(context.Background()); err != nil {
  278. log.Fatalf("failed creating schema resources: %v", err)
  279. }
  280. bg := context.Background()
  281. // BasicDemo(bg, client)
  282. CreateGraph(bg, client)
  283. QueryGithub(bg, client)
  284. QueryAriel(bg, client)
  285. QueryGroupsWithUsers(bg, client)
  286. }