main.go 7.1 KB

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